Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/events.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ end)
-- Set event constants (events are numeric ID keys).
for k, v in pairs(_SCINTILLA) do if type(k) == 'number' then M[v[1]:upper()] = v[1] end end
-- LuaFormatter off
local textadept_events = {'appleevent_odoc','buffer_after_replace_text','buffer_after_switch','buffer_before_replace_text','buffer_before_switch','buffer_deleted','buffer_new','csi','command_text_changed','error','find','find_pane_show','find_pane_hide','find_text_changed','focus','initialized','keypress','menu_clicked','mode_changed','mouse','quit','replace','replace_all','reset_after','reset_before','resume','suspend', 'tab_clicked','tab_close_clicked','unfocus','view_after_switch','view_before_switch','view_new'}
local textadept_events = {'appleevent_odoc','buffer_after_replace_text','buffer_after_switch','buffer_before_replace_text','buffer_before_switch','buffer_deleted','buffer_new','csi','command_text_changed','error','find','find_pane_show','find_pane_hide','find_text_changed','focus','initialized','keypress','menu_clicked','mode_changed','mouse','quit','replace','replace_all','reset_after','reset_before','resume','suspend', 'tab_clicked','tab_close_clicked','unfocus','view_after_switch','view_before_switch','view_new','resize'}
-- LuaFormatter on
for _, v in pairs(textadept_events) do M[v:upper()] = v end

Expand Down
43 changes: 30 additions & 13 deletions src/textadept.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ static void show_error(const char *title, const char *message) {
lua_pop(lua, message_dialog(opts, lua)); // pop results
}

// Pushes the given Scintilla document onto the Lua stack.
// The document must have previously been added with `add_doc()`.
static void lua_pushdoc(lua_State *L, sptr_t doc) {
lua_getfield(L, LUA_REGISTRYINDEX, BUFFERS), lua_rawgetp(L, -1, (sptr_t *)doc),
lua_replace(L, -2);
}

// Pushes the given Scintilla view onto the Lua stack.
// The view must have previously been added with `add_view()`.
static void lua_pushview(lua_State *L, SciObject *view) {
lua_getfield(L, LUA_REGISTRYINDEX, VIEWS), lua_rawgetp(L, -1, view), lua_replace(L, -2);
}

bool emit(const char *name, ...) {
bool ret = false;
if (lua_getglobal(lua, "events") != LUA_TTABLE) return (lua_pop(lua, 1), ret); // pop non-table
Expand All @@ -71,6 +84,10 @@ bool emit(const char *name, ...) {
ref = va_arg(ap, int);
lua_rawgeti(lua, LUA_REGISTRYINDEX, ref), luaL_unref(lua, LUA_REGISTRYINDEX, ref);
break;
case LUA_TBUFFER:
lua_pushdoc(lua, va_arg(ap, sptr_t)); break;
case LUA_TVIEW:
lua_pushview(lua, va_arg(ap, SciObject *)); break;
default: lua_pushnil(lua);
}
va_end(ap);
Expand Down Expand Up @@ -315,12 +332,6 @@ static sptr_t lua_todoc(lua_State *L, int index) {
return (lua_pop(L, 1), doc); // pop doc_pointer
}

// Pushes the given Scintilla document onto the Lua stack.
// The document must have previously been added with `add_doc()`.
static void lua_pushdoc(lua_State *L, sptr_t doc) {
lua_getfield(L, LUA_REGISTRYINDEX, BUFFERS), lua_rawgetp(L, -1, (sptr_t *)doc),
lua_replace(L, -2);
}

// Returns whether or not the given document is the command entry.
static bool is_command_entry(sptr_t doc) {
Expand Down Expand Up @@ -521,7 +532,7 @@ static int buffer_newindex(lua_State *L) {
return (set_command_entry_label(luaL_checkstring(L, 3)), 0);
if (strcmp(lua_tostring(L, 2), "height") == 0 && is_command_entry(lua_todoc(L, 1)))
return (set_command_entry_height(
fmax(luaL_checkinteger(L, 3), SS(command_entry, SCI_TEXTHEIGHT, 0, 0))),
fmax(luaL_checkinteger(L, 3), 1)),
0);
return (lua_settop(L, 3), lua_rawset(L, 1), 0);
}
Expand Down Expand Up @@ -606,12 +617,6 @@ static int get_clipboard_text_lua(lua_State *L) {
return text ? (lua_pushlstring(L, text, len), free(text), 1) : (lua_pushliteral(L, ""), 1);
}

// Pushes the given Scintilla view onto the Lua stack.
// The view must have previously been added with `add_view()`.
static void lua_pushview(lua_State *L, SciObject *view) {
lua_getfield(L, LUA_REGISTRYINDEX, VIEWS), lua_rawgetp(L, -1, view), lua_replace(L, -2);
}

// Pushes onto the Lua stack the given pane, which may contain a Scintilla view or split views.
static void lua_pushsplit(lua_State *L, Pane *pane) {
PaneInfo info = get_pane_info(pane);
Expand Down Expand Up @@ -1157,6 +1162,11 @@ static int view_index(lua_State *L) {
if (*lua_tostring(L, 2) == 'p' && info.is_split) info = get_parent_pane_info(info);
return (info.is_split ? lua_pushinteger(L, info.size) : lua_pushnil(L), 1);
}
if (strcmp(lua_tostring(L, 2), "width") == 0 || strcmp(lua_tostring(L, 2), "height") == 0) {
int width, height;
get_view_dimensions(lua_toview(L, 1), &width, &height);
return (lua_pushinteger(L, (*lua_tostring(L, 2) == 'w') ? width : height), 1);
}
if (lua_getglobal(L, "_SCINTILLA"), lua_pushvalue(L, 2), lua_rawget(L, -2)) {
if (lua_type(L, -1) != LUA_TTABLE) return 1; // constant or function
// If the key is a Scintilla function (4 iface values), return a callable closure.
Expand All @@ -1179,6 +1189,13 @@ static int view_newindex(lua_State *L) {
if (info.is_split) set_pane_size(info.self, fmax(luaL_checkinteger(L, 3), 0));
return 0;
}
if (strcmp(lua_tostring(L, 2), "width") == 0 || strcmp(lua_tostring(L, 2), "height") == 0) {
luaL_argcheck(L,
set_view_dimension(lua_toview(L, 1), fmax(luaL_checkinteger(L, 3), 0), (*lua_tostring(L, 2) == 'w')),
2,
"view is not contained in an adjustable split");
return 0;
}
// If the key is a Scintilla property (more than 4 iface values), call Scintilla to set its value.
if (lua_getglobal(L, "_SCINTILLA"), lua_pushvalue(L, 2),
lua_rawget(L, -2) == LUA_TTABLE && lua_rawlen(L, -1) > 4)
Expand Down
5 changes: 5 additions & 0 deletions src/textadept.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

#include "textadept_platform.h"

// Allows views and buffers to be attached to events.
// Ensure these don't conflict with existing definitions in lua.h.
#define LUA_TBUFFER 14
#define LUA_TVIEW 15

// Textadept's home directory.
extern char *textadept_home;

Expand Down
27 changes: 26 additions & 1 deletion src/textadept_curses.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ static void resize_pane(struct Pane *pane, int rows, int cols, int y, int x) {
resize_pane(pane->child1, ssize, cols, y, x);
resize_pane(pane->child2, rows - ssize - 1, cols, y + ssize + 1, x);
wresize(pane->win, 1, cols), mvwin(pane->win, y + ssize, x); // split bar
} else
} else {
wresize(pane->win, rows, cols), mvwin(pane->win, y, x);
}
pane->rows = rows, pane->cols = cols, pane->y = y, pane->x = x;
if (pane->view) emit("resize", LUA_TVIEW, pane->view, -1);
}

void new_window(SciObject *(*get_view)(void)) {
Expand Down Expand Up @@ -198,6 +200,29 @@ bool unsplit_view(SciObject *view, void (*delete_view)(SciObject *)) {

void delete_scintilla(SciObject *view) { scintilla_delete(view); }

void get_view_dimensions(SciObject *view, int *width, int *height) {
struct Pane *parent = get_parent_pane(root_pane, view);
struct Pane *pane = (parent->child1->view == view) ? parent->child1 : parent->child2;
*width = pane->cols, *height = pane->rows;
}

bool set_view_dimension(SciObject *view, int size, bool width) {
struct Pane *parentPane = get_parent_pane(root_pane, view);
struct Pane *pane = (parentPane->child1->view == view) ? parentPane->child1 : parentPane->child2;
while (pane != root_pane) {
if (parentPane->type == (width ? VSPLIT : HSPLIT)) {
if (parentPane->child1 == pane)
set_pane_size(parentPane, size);
else
set_pane_size(parentPane, width ? parentPane->cols - size : parentPane -> rows - size);
return true;
}
pane = parentPane;
parentPane = get_parent_pane(root_pane, pane);
}
return false;
}

Pane *get_top_pane(void) { return root_pane; }

PaneInfo get_pane_info(Pane *pane) {
Expand Down
53 changes: 47 additions & 6 deletions src/textadept_gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,16 @@ void new_window(SciObject *(*get_view)(void)) {
gtk_box_pack_start(GTK_BOX(editors), get_view(), true, true, 0);
gtk_paned_add1(GTK_PANED(paned), editors);
command_entry_box = gtk_hbox_new(false, 0);
command_entry_label = gtk_label_new(""),
command_entry_label = gtk_label_new("");
gtk_widget_set_size_request(command_entry, -1, 0);
gtk_widget_set_size_request(command_entry_label, -1, 0);
gtk_misc_set_alignment(GTK_MISC(command_entry_label), 0, 0);
gtk_box_pack_start(GTK_BOX(command_entry_box), command_entry_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(command_entry_box), command_entry, true, true, 5);
gtk_widget_set_size_request(command_entry_box, -1, 0);
gtk_paned_add2(GTK_PANED(paned), command_entry_box);
gtk_container_child_set(GTK_CONTAINER(paned), command_entry_box, "shrink", false, NULL);
gtk_container_child_set(GTK_CONTAINER(paned), command_entry_box, "shrink", true, NULL);
gtk_container_child_set(GTK_CONTAINER(paned), command_entry_box, "resize", true, NULL);
gtk_box_pack_start(GTK_BOX(vbox), paned, true, true, 0);

gtk_box_pack_start(GTK_BOX(vbox), new_findbox(), false, false, 0);
Expand All @@ -193,6 +197,7 @@ void new_window(SciObject *(*get_view)(void)) {
gtk_widget_show_all(window), gtk_widget_grab_focus(focused_view);
gtk_widget_hide(menubar), gtk_widget_hide(tabbar), gtk_widget_hide(findbox),
gtk_widget_hide(command_entry_box); // hide initially
set_command_entry_height(0);
}

void set_title(const char *title) { gtk_window_set_title(GTK_WINDOW(window), title); }
Expand Down Expand Up @@ -225,11 +230,16 @@ static bool mouse_clicked(GtkWidget *w, GdkEventButton *event, void *_) {
return (show_context_menu("context_menu", event), true);
}

static bool view_resized(GtkWidget *w, GtkAllocation *allocation, void *_) {
return emit("resize", LUA_TVIEW, (SciObject *)w, -1);
}

SciObject *new_scintilla(void (*notified)(SciObject *, int, SCNotification *, void *)) {
SciObject *view = scintilla_new();
if (notified) g_signal_connect(view, SCINTILLA_NOTIFY, G_CALLBACK(notified), NULL);
g_signal_connect(view, "key-press-event", G_CALLBACK(keypress), NULL);
g_signal_connect(view, "button-press-event", G_CALLBACK(mouse_clicked), NULL);
g_signal_connect(view, "size-allocate", G_CALLBACK(view_resized), NULL);
return view;
}

Expand Down Expand Up @@ -284,6 +294,33 @@ bool unsplit_view(SciObject *view, void (*delete_view)(SciObject *view)) {

void delete_scintilla(SciObject *view) { gtk_widget_destroy(view); }

void get_view_dimensions(SciObject *view, int *width, int *height) {
GtkAllocation allocation;
gtk_widget_get_allocation((GtkWidget *)view, &allocation);
*width = allocation.width, *height = allocation.height;
}

bool set_view_dimension(SciObject *view, int size, bool width) {
GtkWidget *pane, *parentPane;
GtkAllocation allocation;
pane = (GtkWidget *)view, parentPane = gtk_widget_get_parent(pane);
while (GTK_IS_PANED(parentPane)) {
if (gtk_orientable_get_orientation(GTK_ORIENTABLE(parentPane)) == (width ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL)) {
// left/top pane
if (gtk_paned_get_child1(GTK_PANED(parentPane)) == pane)
gtk_paned_set_position(GTK_PANED(parentPane), size);
// right/bottom pane
else
gtk_widget_get_allocation(parentPane, &allocation),
gtk_paned_set_position(GTK_PANED(parentPane), width ? allocation.width - size : allocation.height - size);
return true;
}
pane = parentPane;
parentPane = gtk_widget_get_parent(pane);
}
return false;
}

Pane *get_top_pane(void) {
GtkWidget *pane = focused_view;
while (GTK_IS_PANED(gtk_widget_get_parent(pane))) pane = gtk_widget_get_parent(pane);
Expand Down Expand Up @@ -424,21 +461,25 @@ void focus_command_entry(void) {
if (!gtk_widget_get_visible(command_entry_box))
gtk_widget_show(command_entry_box), gtk_widget_grab_focus(command_entry);
else
gtk_widget_grab_focus(focused_view), gtk_widget_hide(command_entry_box);
gtk_widget_grab_focus(focused_view), gtk_widget_hide(command_entry_box), set_command_entry_height(0);
}
bool is_command_entry_active(void) { return gtk_widget_has_focus(command_entry); }
void set_command_entry_label(const char *text) {
gtk_label_set_text(GTK_LABEL(command_entry_label), text);
}
int get_command_entry_height(void) {
GtkAllocation allocation;
return (gtk_widget_get_allocation(command_entry, &allocation), allocation.height);
return (gtk_widget_get_allocation(command_entry_box, &allocation), allocation.height);
}
void set_command_entry_height(int height) {
GtkWidget *paned = gtk_widget_get_parent(command_entry_box);
GtkAllocation allocation;
GtkAllocation allocation, box_allocation;
gtk_widget_get_allocation(paned, &allocation);
gtk_widget_set_size_request(command_entry, -1, height);
gtk_widget_set_size_request(command_entry_box, -1, height);
gtk_widget_get_allocation(command_entry_box, &box_allocation);
box_allocation.height = height;
// not really supposed to do this but for some reason we can't force it any smaller
gtk_widget_size_allocate(command_entry_box, &box_allocation);
gtk_paned_set_position(GTK_PANED(paned), allocation.height - height);
}

Expand Down
11 changes: 11 additions & 0 deletions src/textadept_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ bool unsplit_view(SciObject *view, void (*delete_view)(SciObject *));
*/
void delete_scintilla(SciObject *view);

/** Gets the dimensions of the requested Scintilla view.
*/
void get_view_dimensions(SciObject *view, int *width, int *height);
/** Sets a dimension (width or height) of the Scintilla widget by resizing split views.
* @param view The Scintilla view to resize.
* @param size The value of the dimension to be set.
* @param width True if setting the width, false if setting the height.
* @return false if the dimension was not settable due to being top level, true otherwise.
*/
bool set_view_dimension(SciObject *view, int size, bool width);

/** Returns the top-most pane that contains Scintilla views. */
Pane *get_top_pane(void);
/** Returns information about the given pane.
Expand Down
28 changes: 28 additions & 0 deletions src/textadept_qt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class ScintillaEventFilter : public QObject {
if (event->type() == QEvent::FocusOut && SCI(watched) == SCI(command_entry))
return static_cast<QFocusEvent *>(event)->reason() == Qt::ActiveWindowFocusReason;

// Notify Textadept when a Scintilla view changes sizes
if (event->type() == QEvent::Resize) {
return emit("resize", LUA_TVIEW, (SciObject *)watched, -1);
}

// Propagate non-keypress events as normal.
if (event->type() != QEvent::KeyPress) return false;

Expand Down Expand Up @@ -173,6 +178,29 @@ bool unsplit_view(SciObject *view, void (*delete_view)(SciObject *)) {

void delete_scintilla(SciObject *view) { delete SCI(view); }

void get_view_dimensions(SciObject *view, int *width, int *height) {
auto widget = static_cast<QWidget *>(SCI(view));
*width = widget->size().width(), *height = widget->size().height();
}

bool set_view_dimension(SciObject *view, int size, bool width) {
QWidget *pane = static_cast<QWidget *>(SCI(view));
QSplitter *parentPane = qobject_cast<QSplitter *>(pane->parentWidget());
while (parentPane) {
if (parentPane->orientation() == (width ? Qt::Horizontal : Qt::Vertical)) {
int max = width ? parentPane->width() : parentPane->height();
if (parentPane->widget(0) == pane)
parentPane->setSizes(QList<int>{size, max - size - parentPane->handleWidth()});
else
parentPane->setSizes(QList<int>{max - size - parentPane->handleWidth(), size});
return true;
}
pane = static_cast<QWidget *>(parentPane);
parentPane = qobject_cast<QSplitter *>(pane->parentWidget());
}
return false;
}

Pane *get_top_pane() {
auto pane = static_cast<QWidget *>(focused_view);
while (qobject_cast<QSplitter *>(pane->parentWidget())) pane = pane->parentWidget();
Expand Down