static gboolean editor_notify_cb(GObject *object, GeanyEditor *editor, SCNotification *nt, gpointer data) { gint lexer, pos, style, min, size; gchar sel[512]; if (nt->nmhdr.code == SCN_CHARADDED && nt->ch == '>') { lexer = sci_get_lexer(editor->sci); if (lexer == SCLEX_XML || lexer == SCLEX_HTML) { pos = sci_get_current_position(editor->sci); style = sci_get_style_at(editor->sci, pos); if ((style <= SCE_H_XCCOMMENT || highlighting_is_string_style(lexer, style)) && !highlighting_is_comment_style(lexer, style)) { CompletionInfo c; InputInfo i; /* Grab the last 512 characters or so */ min = pos - sizeof(sel); if (min < 0) min = 0; size = pos - min; sci_get_text_range(editor->sci, min, pos, sel); if (get_completion(editor, sel, size, &c, &i)) { /* Remove typed opening tag */ sci_set_selection_start(editor->sci, min + i.tag_start); sci_set_selection_end(editor->sci, pos); sci_replace_sel(editor->sci, ""); pos -= (size - i.tag_start); /* pos has changed while deleting */ /* Insert the completion */ editor_insert_snippet(editor, pos, c.completion); sci_scroll_caret(editor->sci); g_free((gchar *)c.completion); return TRUE; } } } } return FALSE; }
static PyObject * Scintilla_get_style_at(Scintilla *self, PyObject *args, PyObject *kwargs) { gint pos = -1, style; static gchar *kwlist[] = { "pos", NULL }; SCI_RET_IF_FAIL(self); if (PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &pos)) { if (pos == -1) pos = sci_get_current_position(self->sci); style = sci_get_style_at(self->sci, pos); return Py_BuildValue("i", style); } Py_RETURN_NONE; }
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { DocInfo *dinfo = user_data; GeanyEditor *editor; cairo_t *cr; gdouble width, height; gdouble x = 0.0, y = 0.0; /*gint layout_h;*/ gint count; GString *str; if (dinfo == NULL || page_nr >= dinfo->n_pages) return; editor = dinfo->doc->editor; if (dinfo->n_pages > 0) { gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages; gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text); g_free(text); } #ifdef GEANY_PRINT_DEBUG geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d", page_nr, dinfo->n_pages, dinfo->lines_per_page); #endif str = g_string_sized_new(256); cr = gtk_print_context_get_cairo_context(context); width = gtk_print_context_get_width(context); height = gtk_print_context_get_height(context); cairo_set_source_rgb(cr, 0, 0, 0); #ifdef GEANY_PRINT_DEBUG cairo_set_line_width(cr, 0.2); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); #endif cairo_move_to(cr, 0, 0); pango_layout_set_width(dinfo->layout, width * PANGO_SCALE); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT); pango_layout_set_ellipsize(dinfo->layout, FALSE); pango_layout_set_justify(dinfo->layout, FALSE); if (printing_prefs.print_page_header) add_page_header(dinfo, cr, width, page_nr); count = 0; /* the actual line counter for the current page, might be different from * dinfo->cur_line due to possible line breaks */ while (count < dinfo->lines_per_page) { gchar c = 'a'; gint style = -1; PangoAttrList *layout_attr; PangoAttribute *attr; gint colours[3] = { 0 }; gboolean add_linenumber = TRUE; gboolean at_eol; while (count < dinfo->lines_per_page && c != '\0') { at_eol = FALSE; g_string_erase(str, 0, str->len); /* clear the string */ /* line numbers */ if (printing_prefs.print_line_numbers && add_linenumber) { /* if we had a wrapped line on the last page which needs to be continued, don't * add a line number */ if (dinfo->long_line) { add_linenumber = FALSE; } else { gchar *line_number = NULL; gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1); gchar *fill = g_strnfill( dinfo->max_line_number_margin - cur_line_number_margin - 1, ' '); line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1); g_string_append(str, line_number); dinfo->cur_line++; /* increase document line */ add_linenumber = FALSE; style = STYLE_LINENUMBER; c = 'a'; /* dummy value */ g_free(fill); g_free(line_number); } } /* data */ else { style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos); c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c == '\0' || style == -1) { /* if c gets 0, we are probably out of document boundaries, * so stop to break out of outer loop */ count = dinfo->lines_per_page; break; } dinfo->cur_pos++; /* convert tabs to spaces which seems to be better than using Pango tabs */ if (c == '\t') { gint tab_width = sci_get_tab_width(editor->sci); gchar *s = g_strnfill(tab_width, ' '); g_string_append(str, s); g_free(s); } /* don't add line breaks, they are handled manually below */ else if (c == '\r' || c == '\n') { gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); at_eol = TRUE; if (c == '\r' && c_next == '\n') dinfo->cur_pos++; /* skip LF part of CR/LF */ } else { g_string_append_c(str, c); /* finally add the character */ /* handle UTF-8: since we add char by char (better: byte by byte), we need to * keep UTF-8 characters together(e.g. two bytes for one character) * the input is always UTF-8 and c is signed, so all non-Ascii * characters are less than 0 and consist of all bytes less than 0. * style doesn't change since it is only one character with multiple bytes. */ while (c < 0) { c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos); if (c < 0) { /* only add the byte when it is part of the UTF-8 character * otherwise we could add e.g. a '\n' and it won't be visible in the * printed document */ g_string_append_c(str, c); dinfo->cur_pos++; } } } } if (! at_eol) { /* set text */ pango_layout_set_text(dinfo->layout, str->str, -1); /* attributes */ layout_attr = pango_attr_list_new(); /* foreground colour */ get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]); attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]); ADD_ATTR(layout_attr, attr); /* background colour */ get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]); attr = pango_attr_background_new(colours[0], colours[1], colours[2]); ADD_ATTR(layout_attr, attr); /* bold text */ if (dinfo->styles[style][BOLD]) { attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD); ADD_ATTR(layout_attr, attr); } /* italic text */ if (dinfo->styles[style][ITALIC]) { attr = pango_attr_style_new(PANGO_STYLE_ITALIC); ADD_ATTR(layout_attr, attr); } pango_layout_set_attributes(dinfo->layout, layout_attr); pango_layout_context_changed(dinfo->layout); pango_attr_list_unref(layout_attr); } cairo_get_current_point(cr, &x, &y); /* normal line break at eol character in document */ if (at_eol) { /*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/ /*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/ cairo_move_to(cr, 0, y + dinfo->line_height); count++; /* we added a new document line so request a new line number */ add_linenumber = TRUE; } else { gint x_offset = 0; /* maybe we need to force a line break because of too long line */ if (x >= (width - dinfo->font_width)) { /* don't start the line at horizontal origin because we need to skip the * line number margin */ if (printing_prefs.print_line_numbers) { x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width; } /*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/ /*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/ /* this is faster but not exactly the same as above */ cairo_move_to(cr, x_offset, y + dinfo->line_height); cairo_get_current_point(cr, &x, &y); count++; } if (count < dinfo->lines_per_page) { /* str->len is counted in bytes not characters, so use g_utf8_strlen() */ x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width); if (dinfo->long_line && count == 0) { x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width; dinfo->long_line = FALSE; } pango_cairo_show_layout(cr, dinfo->layout); cairo_move_to(cr, x + x_offset, y); } else /* we are on a wrapped line but we are out of lines on this page, so continue * the current line on the next page and remember to continue in current line */ dinfo->long_line = TRUE; } } } if (printing_prefs.print_line_numbers) { /* print a thin line between the line number margin and the data */ gint y_start = 0; if (printing_prefs.print_page_header) y_start = (dinfo->line_height * 3) - 2; /* "- 2": to connect the line number line to * the page header frame */ cairo_set_line_width(cr, 0.3); cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start); cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y + dinfo->line_height); /* y is last added line, we reuse it */ cairo_stroke(cr); } if (printing_prefs.print_page_numbers) { gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1); pango_layout_set_markup(dinfo->layout, line, -1); pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER); cairo_move_to(cr, 0, height - dinfo->line_height); pango_cairo_show_layout(cr, dinfo->layout); g_free(line); #ifdef GEANY_PRINT_DEBUG cairo_set_line_width(cr, 0.3); cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height)); cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height)); cairo_stroke(cr); #endif } g_string_free(str, TRUE); }
gboolean sc_speller_is_text(GeanyDocument *doc, gint pos) { gint lexer, style; g_return_val_if_fail(doc != NULL, FALSE); g_return_val_if_fail(pos >= 0, FALSE); style = sci_get_style_at(doc->editor->sci, pos); /* early out for the default style */ if (style == STYLE_DEFAULT) return TRUE; lexer = scintilla_send_message(doc->editor->sci, SCI_GETLEXER, 0, 0); switch (lexer) { case SCLEX_ABAQUS: { switch (style) { case SCE_ABAQUS_DEFAULT: case SCE_ABAQUS_COMMENT: case SCE_ABAQUS_COMMENTBLOCK: case SCE_ABAQUS_STRING: return TRUE; default: return FALSE; } break; } case SCLEX_ADA: { switch (style) { case SCE_ADA_DEFAULT: case SCE_ADA_COMMENTLINE: case SCE_ADA_STRING: case SCE_ADA_STRINGEOL: case SCE_ADA_CHARACTER: case SCE_ADA_CHARACTEREOL: return TRUE; default: return FALSE; } break; } case SCLEX_ASM: { switch (style) { case SCE_ASM_DEFAULT: case SCE_ASM_COMMENT: case SCE_ASM_COMMENTBLOCK: case SCE_ASM_STRING: case SCE_ASM_STRINGEOL: case SCE_ASM_CHARACTER: return TRUE; default: return FALSE; } break; } case SCLEX_BASH: { switch (style) { case SCE_SH_DEFAULT: case SCE_SH_COMMENTLINE: case SCE_SH_STRING: case SCE_SH_CHARACTER: return TRUE; default: return FALSE; } break; } case SCLEX_BATCH: { switch (style) { case SCE_BAT_DEFAULT: case SCE_BAT_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_CAML: { switch (style) { case SCE_CAML_DEFAULT: case SCE_CAML_COMMENT: case SCE_CAML_COMMENT1: case SCE_CAML_COMMENT2: case SCE_CAML_COMMENT3: case SCE_CAML_STRING: case SCE_CAML_CHAR: return TRUE; default: return FALSE; } break; } case SCLEX_CMAKE: { switch (style) { case SCE_CMAKE_DEFAULT: case SCE_CMAKE_COMMENT: case SCE_CMAKE_STRINGDQ: case SCE_CMAKE_STRINGLQ: case SCE_CMAKE_STRINGRQ: return TRUE; default: return FALSE; } break; } #ifdef SCE_PAS_DEFAULT case SCLEX_PASCAL: { switch (style) { case SCE_PAS_DEFAULT: case SCE_PAS_COMMENT: case SCE_PAS_COMMENT2: case SCE_PAS_COMMENTLINE: case SCE_PAS_STRING: case SCE_PAS_CHARACTER: return TRUE; default: return FALSE; } break; } #else case SCLEX_PASCAL: #endif case SCLEX_COBOL: case SCLEX_CPP: { switch (style) { case SCE_C_DEFAULT: case SCE_C_COMMENT: case SCE_C_COMMENTLINE: case SCE_C_COMMENTDOC: case SCE_C_STRING: case SCE_C_CHARACTER: case SCE_C_STRINGEOL: case SCE_C_COMMENTLINEDOC: return TRUE; default: return FALSE; } break; } case SCLEX_COFFEESCRIPT: { switch (style) { case SCE_COFFEESCRIPT_CHARACTER: case SCE_COFFEESCRIPT_COMMENTBLOCK: case SCE_COFFEESCRIPT_COMMENTDOCKEYWORD: case SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR: case SCE_COFFEESCRIPT_COMMENTLINEDOC: case SCE_COFFEESCRIPT_STRING: case SCE_COFFEESCRIPT_STRINGEOL: case SCE_COFFEESCRIPT_STRINGRAW: return TRUE; default: return FALSE; } break; } case SCLEX_CSS: { switch (style) { case SCE_CSS_DEFAULT: case SCE_CSS_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_D: { switch (style) { case SCE_D_DEFAULT: case SCE_D_COMMENT: case SCE_D_COMMENTLINE: case SCE_D_COMMENTDOC: case SCE_D_COMMENTNESTED: case SCE_D_STRING: case SCE_D_STRINGEOL: case SCE_D_CHARACTER: case SCE_D_COMMENTLINEDOC: return TRUE; default: return FALSE; } break; } case SCLEX_DIFF: { switch (style) { case SCE_DIFF_DEFAULT: case SCE_DIFF_COMMENT: case SCE_DIFF_HEADER: return TRUE; default: return FALSE; } break; } case SCLEX_ERLANG: { switch (style) { case SCE_ERLANG_DEFAULT: case SCE_ERLANG_COMMENT: case SCE_ERLANG_STRING: case SCE_ERLANG_CHARACTER: case SCE_ERLANG_COMMENT_FUNCTION: case SCE_ERLANG_COMMENT_MODULE: case SCE_ERLANG_COMMENT_DOC: case SCE_ERLANG_COMMENT_DOC_MACRO: return TRUE; default: return FALSE; } break; } case SCLEX_F77: case SCLEX_FORTRAN: { switch (style) { case SCE_F_DEFAULT: case SCE_F_COMMENT: case SCE_F_STRING1: case SCE_F_STRING2: case SCE_F_STRINGEOL: return TRUE; default: return FALSE; } break; } case SCLEX_FORTH: { switch (style) { case SCE_FORTH_DEFAULT: case SCE_FORTH_COMMENT: case SCE_FORTH_COMMENT_ML: case SCE_FORTH_STRING: case SCE_FORTH_LOCALE: return TRUE; default: return FALSE; } break; } case SCLEX_FREEBASIC: { switch (style) { case SCE_B_DEFAULT: case SCE_B_COMMENT: case SCE_B_STRING: case SCE_B_STRINGEOL: case SCE_B_CONSTANT: return TRUE; default: return FALSE; } break; } case SCLEX_HASKELL: { switch (style) { case SCE_HA_DEFAULT: case SCE_HA_COMMENTLINE: case SCE_HA_COMMENTBLOCK: case SCE_HA_COMMENTBLOCK2: case SCE_HA_COMMENTBLOCK3: case SCE_HA_STRING: case SCE_HA_CHARACTER: case SCE_HA_DATA: return TRUE; default: return FALSE; } break; } case SCLEX_HTML: case SCLEX_XML: { switch (style) { case SCE_H_DEFAULT: case SCE_H_TAGUNKNOWN: case SCE_H_ATTRIBUTEUNKNOWN: case SCE_H_DOUBLESTRING: case SCE_H_SINGLESTRING: case SCE_H_COMMENT: case SCE_H_CDATA: case SCE_H_VALUE: /* really? */ case SCE_H_SGML_DEFAULT: case SCE_H_SGML_COMMENT: case SCE_H_SGML_DOUBLESTRING: case SCE_H_SGML_SIMPLESTRING: case SCE_H_SGML_1ST_PARAM_COMMENT: case SCE_HJ_COMMENT: case SCE_HJ_COMMENTLINE: case SCE_HJ_COMMENTDOC: case SCE_HJ_DOUBLESTRING: case SCE_HJ_SINGLESTRING: case SCE_HJ_STRINGEOL: case SCE_HB_COMMENTLINE: case SCE_HB_STRING: case SCE_HB_STRINGEOL: case SCE_HBA_COMMENTLINE: case SCE_HBA_STRING: case SCE_HBA_STRINGEOL: case SCE_HJA_COMMENT: case SCE_HJA_COMMENTLINE: case SCE_HJA_COMMENTDOC: case SCE_HJA_DOUBLESTRING: case SCE_HJA_SINGLESTRING: case SCE_HJA_STRINGEOL: case SCE_HP_COMMENTLINE: case SCE_HP_STRING: case SCE_HP_CHARACTER: case SCE_HP_TRIPLE: case SCE_HP_TRIPLEDOUBLE: case SCE_HPA_COMMENTLINE: case SCE_HPA_STRING: case SCE_HPA_CHARACTER: case SCE_HPA_TRIPLE: case SCE_HPA_TRIPLEDOUBLE: case SCE_HPHP_SIMPLESTRING: case SCE_HPHP_HSTRING: case SCE_HPHP_COMMENT: case SCE_HPHP_COMMENTLINE: return TRUE; default: return FALSE; } break; } case SCLEX_LATEX: { switch (style) { case SCE_L_DEFAULT: case SCE_L_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_LISP: { switch (style) { case SCE_LISP_DEFAULT: case SCE_LISP_COMMENT: case SCE_LISP_STRING: case SCE_LISP_STRINGEOL: case SCE_LISP_MULTI_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_LUA: { switch (style) { case SCE_LUA_DEFAULT: case SCE_LUA_COMMENT: case SCE_LUA_COMMENTLINE: case SCE_LUA_COMMENTDOC: case SCE_LUA_STRING: case SCE_LUA_CHARACTER: case SCE_LUA_LITERALSTRING: case SCE_LUA_STRINGEOL: return TRUE; default: return FALSE; } break; } case SCLEX_MAKEFILE: { switch (style) { case SCE_MAKE_DEFAULT: case SCE_MAKE_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_MARKDOWN: { return TRUE; break; } case SCLEX_MATLAB: case SCLEX_OCTAVE: { switch (style) { case SCE_MATLAB_DEFAULT: case SCE_MATLAB_COMMENT: case SCE_MATLAB_STRING: case SCE_MATLAB_DOUBLEQUOTESTRING: return TRUE; default: return FALSE; } break; } case SCLEX_NSIS: { switch (style) { case SCE_NSIS_DEFAULT: case SCE_NSIS_COMMENT: case SCE_NSIS_STRINGDQ: case SCE_NSIS_STRINGLQ: case SCE_NSIS_STRINGRQ: case SCE_NSIS_STRINGVAR: case SCE_NSIS_COMMENTBOX: return TRUE; default: return FALSE; } break; } case SCLEX_PERL: { switch (style) { case SCE_PL_DEFAULT: case SCE_PL_COMMENTLINE: case SCE_PL_STRING: case SCE_PL_CHARACTER: case SCE_PL_POD: case SCE_PL_POD_VERB: case SCE_PL_LONGQUOTE: /* do we want SCE_PL_STRING_* too? */ return TRUE; default: return FALSE; } break; } case SCLEX_PO: { switch (style) { case SCE_PO_DEFAULT: case SCE_PO_COMMENT: case SCE_PO_MSGID_TEXT: case SCE_PO_MSGSTR_TEXT: case SCE_PO_MSGCTXT_TEXT: return TRUE; default: return FALSE; } break; } case SCLEX_POWERSHELL: { switch (style) { case SCE_POWERSHELL_DEFAULT: case SCE_POWERSHELL_COMMENT: case SCE_POWERSHELL_STRING: case SCE_POWERSHELL_COMMENTSTREAM: case SCE_POWERSHELL_COMMENTDOCKEYWORD: return TRUE; default: return FALSE; } break; } case SCLEX_PROPERTIES: { switch (style) { case SCE_PROPS_DEFAULT: case SCE_PROPS_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_PYTHON: { switch (style) { case SCE_P_DEFAULT: case SCE_P_COMMENTLINE: case SCE_P_STRING: case SCE_P_CHARACTER: case SCE_P_TRIPLE: case SCE_P_TRIPLEDOUBLE: case SCE_P_COMMENTBLOCK: case SCE_P_STRINGEOL: return TRUE; default: return FALSE; } break; } case SCLEX_R: { switch (style) { case SCE_R_DEFAULT: case SCE_R_COMMENT: case SCE_R_STRING: case SCE_R_STRING2: return TRUE; default: return FALSE; } break; } case SCLEX_RUBY: { switch (style) { case SCE_RB_DEFAULT: case SCE_RB_COMMENTLINE: case SCE_RB_STRING: case SCE_RB_CHARACTER: case SCE_RB_POD: return TRUE; default: return FALSE; } break; } case SCLEX_SQL: { switch (style) { case SCE_SQL_DEFAULT: case SCE_SQL_COMMENT: case SCE_SQL_COMMENTLINE: case SCE_SQL_COMMENTDOC: case SCE_SQL_STRING: case SCE_SQL_CHARACTER: case SCE_SQL_SQLPLUS_COMMENT: return TRUE; default: return FALSE; } break; } case SCLEX_TCL: { switch (style) { case SCE_TCL_DEFAULT: case SCE_TCL_COMMENT: case SCE_TCL_COMMENTLINE: case SCE_TCL_IN_QUOTE: return TRUE; default: return FALSE; } break; } case SCLEX_TXT2TAGS: { return TRUE; break; } case SCLEX_VERILOG: { switch (style) { case SCE_V_DEFAULT: case SCE_V_COMMENT: case SCE_V_COMMENTLINE: case SCE_V_COMMENTLINEBANG: case SCE_V_STRING: case SCE_V_STRINGEOL: return TRUE; default: return FALSE; } break; } case SCLEX_VHDL: { switch (style) { case SCE_VHDL_DEFAULT: case SCE_VHDL_COMMENT: case SCE_VHDL_COMMENTLINEBANG: case SCE_VHDL_STRING: case SCE_VHDL_STRINGEOL: return TRUE; default: return FALSE; } break; } case SCLEX_YAML: { switch (style) { case SCE_YAML_DEFAULT: case SCE_YAML_COMMENT: case SCE_YAML_TEXT: return TRUE; default: return FALSE; } break; } } /* if the current lexer was not handled, let's say the passed position contains * valid text to not ignore more than we want */ return TRUE; }