aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/scintilla.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scintilla.c')
-rw-r--r--src/scintilla.c349
1 files changed, 0 insertions, 349 deletions
diff --git a/src/scintilla.c b/src/scintilla.c
deleted file mode 100644
index f58b6f4..0000000
--- a/src/scintilla.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2012-2021 Robin Haberkorn
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "sciteco.h"
-#include "string-utils.h"
-#include "error.h"
-#include "parser.h"
-#include "core-commands.h"
-#include "undo.h"
-#include "expressions.h"
-#include "interface.h"
-#include "scintilla.h"
-
-teco_symbol_list_t teco_symbol_list_scintilla = {NULL, 0};
-teco_symbol_list_t teco_symbol_list_scilexer = {NULL, 0};
-
-/*
- * FIXME: Could be static.
- */
-TECO_DEFINE_UNDO_OBJECT_OWN(scintilla_message, teco_machine_scintilla_t, /* don't delete */);
-
-/** @memberof teco_symbol_list_t */
-void
-teco_symbol_list_init(teco_symbol_list_t *ctx, const teco_symbol_entry_t *entries, gint size,
- gboolean case_sensitive)
-{
- memset(ctx, 0, sizeof(*ctx));
- ctx->entries = entries;
- ctx->size = size;
- ctx->cmp_fnc = case_sensitive ? strncmp : g_ascii_strncasecmp;
-}
-
-/**
- * @note Since symbol lists are presorted constant arrays we can do a simple
- * binary search.
- * This does not use bsearch() since we'd have to prepend `prefix` in front of
- * the name.
- *
- * @memberof teco_symbol_list_t
- */
-gint
-teco_symbol_list_lookup(teco_symbol_list_t *ctx, const gchar *name, const gchar *prefix)
-{
- gsize name_len = strlen(name);
-
- gsize prefix_skip = strlen(prefix);
- if (!ctx->cmp_fnc(name, prefix, prefix_skip))
- prefix_skip = 0;
-
- gint left = 0;
- gint right = ctx->size - 1;
-
- while (left <= right) {
- gint cur = left + (right-left)/2;
- gint cmp = ctx->cmp_fnc(ctx->entries[cur].name + prefix_skip,
- name, name_len + 1);
-
- if (!cmp)
- return ctx->entries[cur].value;
-
- if (cmp > 0)
- right = cur-1;
- else /* cmp < 0 */
- left = cur+1;
- }
-
- return -1;
-}
-
-/**
- * Auto-complete a Scintilla symbol.
- *
- * @param ctx The symbol list.
- * @param symbol The symbol to auto-complete or NULL.
- * @param insert String to initialize with the completion.
- * @return TRUE in case of an unambiguous completion.
- *
- * @memberof teco_symbol_list_t
- */
-gboolean
-teco_symbol_list_auto_complete(teco_symbol_list_t *ctx, const gchar *symbol, teco_string_t *insert)
-{
- memset(insert, 0, sizeof(*insert));
-
- if (!symbol)
- symbol = "";
- gsize symbol_len = strlen(symbol);
-
- if (G_UNLIKELY(!ctx->list))
- for (gint i = ctx->size; i; i--)
- ctx->list = g_list_prepend(ctx->list, (gchar *)ctx->entries[i-1].name);
-
- /* NOTE: element data must not be freed */
- g_autoptr(GList) glist = g_list_copy(ctx->list);
- guint glist_len = 0;
-
- gsize prefix_len = 0;
-
- for (GList *entry = g_list_first(glist), *next = g_list_next(entry);
- entry != NULL;
- entry = next, next = entry ? g_list_next(entry) : NULL) {
- if (g_ascii_strncasecmp(entry->data, symbol, symbol_len) != 0) {
- glist = g_list_delete_link(glist, entry);
- continue;
- }
-
- teco_string_t glist_str;
- glist_str.data = (gchar *)glist->data + symbol_len;
- glist_str.len = strlen(glist_str.data);
-
- gsize len = teco_string_casediff(&glist_str, (gchar *)entry->data + symbol_len,
- strlen(entry->data) - symbol_len);
- if (!prefix_len || len < prefix_len)
- prefix_len = len;
-
- glist_len++;
- }
-
- if (prefix_len > 0) {
- teco_string_init(insert, (gchar *)glist->data + symbol_len, prefix_len);
- } else if (glist_len > 1) {
- for (GList *entry = g_list_first(glist);
- entry != NULL;
- entry = g_list_next(entry)) {
- teco_interface_popup_add(TECO_POPUP_PLAIN, entry->data,
- strlen(entry->data), FALSE);
- }
-
- teco_interface_popup_show();
- }
-
- return glist_len == 1;
-}
-
-/*
- * Command states
- */
-
-/*
- * FIXME: This state could be static.
- */
-TECO_DECLARE_STATE(teco_state_scintilla_lparam);
-
-static gboolean
-teco_scintilla_parse_symbols(teco_machine_scintilla_t *scintilla, const teco_string_t *str, GError **error)
-{
- if (teco_string_contains(str, '\0')) {
- g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
- "Scintilla symbol names must not contain null-byte");
- return FALSE;
- }
-
- g_auto(GStrv) symbols = g_strsplit(str->data, ",", -1);
-
- if (!symbols[0])
- return TRUE;
- if (*symbols[0]) {
- gint v = teco_symbol_list_lookup(&teco_symbol_list_scintilla, symbols[0], "SCI_");
- if (v < 0) {
- g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED,
- "Unknown Scintilla message symbol \"%s\"",
- symbols[0]);
- return FALSE;
- }
- scintilla->iMessage = v;
- }
-
- if (!symbols[1])
- return TRUE;
- if (*symbols[1]) {
- gint v = teco_symbol_list_lookup(&teco_symbol_list_scilexer, symbols[1], "");
- if (v < 0) {
- g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED,
- "Unknown Scintilla Lexer symbol \"%s\"",
- symbols[1]);
- return FALSE;
- }
- scintilla->wParam = v;
- }
-
- if (!symbols[2])
- return TRUE;
- if (*symbols[2]) {
- gint v = teco_symbol_list_lookup(&teco_symbol_list_scilexer, symbols[2], "");
- if (v < 0) {
- g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED,
- "Unknown Scintilla Lexer symbol \"%s\"",
- symbols[2]);
- return FALSE;
- }
- scintilla->lParam = v;
- }
-
- return TRUE;
-}
-
-static teco_state_t *
-teco_state_scintilla_symbols_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error)
-{
- if (ctx->mode > TECO_MODE_NORMAL)
- return &teco_state_scintilla_lparam;
-
- /*
- * NOTE: This is more memory efficient than pushing the individual
- * members of teco_machine_scintilla_t and we won't need to define
- * undo methods for the Scintilla types.
- */
- if (ctx->parent.must_undo)
- teco_undo_object_scintilla_message_push(&ctx->scintilla);
- memset(&ctx->scintilla, 0, sizeof(ctx->scintilla));
-
- if ((str->len > 0 && !teco_scintilla_parse_symbols(&ctx->scintilla, str, error)) ||
- !teco_expressions_eval(FALSE, error))
- return NULL;
-
- teco_int_t value;
-
- if (!ctx->scintilla.iMessage) {
- if (!teco_expressions_args()) {
- g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
- "<ES> command requires at least a message code");
- return NULL;
- }
-
- if (!teco_expressions_pop_num_calc(&value, 0, error))
- return NULL;
- ctx->scintilla.iMessage = value;
- }
- if (!ctx->scintilla.wParam) {
- if (!teco_expressions_pop_num_calc(&value, 0, error))
- return NULL;
- ctx->scintilla.wParam = value;
- }
-
- return &teco_state_scintilla_lparam;
-}
-
-/* in cmdline.c */
-gboolean teco_state_scintilla_symbols_process_edit_cmd(teco_machine_main_t *ctx, teco_machine_t *parent_ctx, gchar key, GError **error);
-
-/*$ ES scintilla message
- * -- Send Scintilla message
- * [lParam[,wParam]]ESmessage[,wParam[,lParam]]$[lParam]$ -> result
- *
- * Send Scintilla message with code specified by symbolic
- * name <message>, <wParam> and <lParam>.
- * <wParam> may be symbolic when specified as part of the
- * first string argument.
- * If not it is popped from the stack.
- * <lParam> may be specified as a constant string whose
- * pointer is passed to Scintilla if specified as the second
- * string argument.
- * If the second string argument is empty, <lParam> is popped
- * from the stack instead.
- * Parameters popped from the stack may be omitted, in which
- * case 0 is implied.
- * The message's return value is pushed onto the stack.
- *
- * All messages defined by Scintilla (as C macros) can be
- * used by passing their name as a string to ES
- * (e.g. ESSCI_LINESONSCREEN...).
- * The \(lqSCI_\(rq prefix may be omitted and message symbols
- * are case-insensitive.
- * Only the Scintilla lexer symbols (SCLEX_..., SCE_...)
- * may be used symbolically with the ES command as <wParam>,
- * other values must be passed as integers on the stack.
- * In interactive mode, symbols may be auto-completed by
- * pressing Tab.
- * String-building characters are by default interpreted
- * in the string arguments.
- *
- * .BR Warning :
- * Almost all Scintilla messages may be dispatched using
- * this command.
- * \*(ST does not keep track of the editor state changes
- * performed by these commands and cannot undo them.
- * You should never use it to change the editor state
- * (position changes, deletions, etc.) or otherwise
- * rub out will result in an inconsistent editor state.
- * There are however exceptions:
- * - In the editor profile and batch mode in general,
- * the ES command may be used freely.
- * - In the ED hook macro (register \(lqED\(rq),
- * when a file is added to the ring, most destructive
- * operations can be performed since rubbing out the
- * EB command responsible for the hook execution also
- * removes the buffer from the ring again.
- * - As part of function key macros that immediately
- * terminate the command line.
- */
-TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_symbols,
- .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_scintilla_symbols_process_edit_cmd,
- .expectstring.last = FALSE
-);
-
-static teco_state_t *
-teco_state_scintilla_lparam_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error)
-{
- if (ctx->mode > TECO_MODE_NORMAL)
- return &teco_state_start;
-
- if (teco_string_contains(str, '\0')) {
- g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
- "Scintilla lParam string must not contain null-byte.");
- return NULL;
- }
-
- if (!ctx->scintilla.lParam) {
- if (str->len > 0) {
- ctx->scintilla.lParam = (sptr_t)str->data;
- } else {
- teco_int_t v;
- if (!teco_expressions_pop_num_calc(&v, 0, error))
- return NULL;
- ctx->scintilla.lParam = v;
- }
- }
-
- teco_expressions_push(teco_interface_ssm(ctx->scintilla.iMessage,
- ctx->scintilla.wParam,
- ctx->scintilla.lParam));
-
- return &teco_state_start;
-}
-
-TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_lparam);