Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added plugin keyrecord #460

Merged
merged 3 commits into from Apr 30, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions keyrecord/AUTHORS
@@ -0,0 +1 @@
Artur Riazanov <tunyash(at)gmail(dot)com>
339 changes: 339 additions & 0 deletions keyrecord/COPYING

Large diffs are not rendered by default.

Empty file added keyrecord/ChangeLog
Empty file.
10 changes: 10 additions & 0 deletions keyrecord/ChangeLog~
@@ -0,0 +1,10 @@
2013-10-05 Pavel Roschin - version 0.2
* add removing pairing brace by Shift+BackSpace
* do not add semicolon in #define-s
* add semicolon after class and struct
* now works with GTK3+ (thanks Matthew Brush for patch http://pastebin.geany.org/r2VKS/)
* added scrollbar for settings
* improve semicolon completion
* added help
* added Tab jump to enclosed char (thanks Thomas Martitz:
https://github.com/kugel-/geany-plugins/commit/7f19c3035abf6f8a7fa66c7b4c1efe0851cb2f83)
4 changes: 4 additions & 0 deletions keyrecord/Makefile.am
@@ -0,0 +1,4 @@
include $(top_srcdir)/build/vars.auxfiles.mk

SUBDIRS = src
plugin = keyrecord
Empty file added keyrecord/NEWS
Empty file.
33 changes: 33 additions & 0 deletions keyrecord/README
@@ -0,0 +1,33 @@
Keystrokes recorder
===================

.. contents::

About
-----

This plugin allows you to record a sequence of keystrokes and to replay it
several times.

Features
--------

It's only basic features at the moment.

Usage
-----

After installed successfully, load the plugin in Geany's plugin manager. You
have to set up keybindings for recording and for replaing keystrokes. Work
with the plugin then looks like follows: [record hotkey] [keystroke] ...
[keystroke] [record hotkey] ... some work ... [play hotkey].

Requirements
------------

* GTK >= 2.8.0

Contact developers
------------------

Artur Riazanov <tunyash(at)gmail(dot)com>
56 changes: 56 additions & 0 deletions keyrecord/README~
@@ -0,0 +1,56 @@
Auto-close brackets
===================

.. image:: http://dl.dropboxusercontent.com/u/59878867/geany-autoclose.gif
:width: 778
:alt: autoclose plugin
:align: right

.. contents::

About
-----

This plugin enables auto-closing features. Auto-closing works while you typing
and intellectually helps you to write code.

Features
--------

* auto-close for: { }, [ ], ( ), " ", ' ', < >, ` `
* customizeable auto-closing inside strings and comments
* delete pairing character if you pressed BackSpace
* suppress inserting one char twice (if you type "{}" you will get "{}", not
"{}}")
* enclose selected text into brackets instead of removing selection (select
text and type "(" or ")" to enclose selection into "()")
* keep selection when enclosing
* for C-like languages enclosing selection into "{}" makes auto-indentation
(select text and type "{" or "}" - text will be enclosed and indented)
* enclosing in {} moves cursor to beginning (before "{" character)
* for C-like languages to insert {}-block you do not need to select text
precisely: plugin detects boundaries automatically, just ensure that selection
covers lines you need to indent (works like TAB indentation)
* fix auto-indent inside {} (makes full indent for this block)
* auto-close curly bracket by pressing Enter
* auto-close functions (``"sin(|" -> "sin(|);"``) with doubling suppression
(for C/C++ languages only)
* remove paring brace when pressing Shift+BackSpace, unindent {}-blocks
* add semicolon after ``struct {|};`` and ``class {|};``
* move cursor to closed char by pressing Tab

Usage
-----

After installed successfully, load the plugin in Geany's plugin manager. You may
change module preferences.

Requirements
------------

* GTK >= 2.8.0

Contact developers
------------------

Pavel Roschin <rpg89(at)post(dot)ru>
10 changes: 10 additions & 0 deletions keyrecord/src/Makefile.am
@@ -0,0 +1,10 @@
include $(top_srcdir)/build/vars.build.mk
plugin = autoclose

geanyplugins_LTLIBRARIES = autoclose.la

autoclose_la_SOURCES = autoclose.c
autoclose_la_CPPFLAGS = $(AM_CPPFLAGS) -DG_LOG_DOMAIN=\"AutoClose\"
autoclose_la_LIBADD = $(COMMONLIBS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check for right prefix -> s/autoclose/keyrecord


include $(top_srcdir)/build/cppcheck.mk
228 changes: 228 additions & 0 deletions keyrecord/src/keyrecord.c
@@ -0,0 +1,228 @@
/*
* demoplugin.c - this file is part of Geany, a fast and lightweight IDE
*
* Copyright 2007-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* Copyright 2007-2012 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/



/**
* Demo plugin - example of a basic plugin for Geany. Adds a menu item to the
* Tools menu.
*
* Note: This is not installed by default, but (on *nix) you can build it as follows:
* cd plugins
* make demoplugin.so
*
* Then copy or symlink the plugins/demoplugin.so file to ~/.config/geany/plugins
* - it will be loaded at next startup.
*/


#include "geanyplugin.h" /* plugin API, always comes first */
#include "keybindings.h"
#include <geany.h>
#include "Scintilla.h" /* for the SCNotification struct */
#include "stdio.h"
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <assert.h>
//#undef geany
/* text to be shown in the plugin dialog */
static GeanyPlugin* g_plugin = NULL;
static gboolean recording;
static GdkEventKey** recorded_pattern;
static guint recorded_size;
int CAPACITY = 2;
GeanyKeyBinding *record, *play;
GtkWidget *cur_widget;
static gboolean is_record_key(GdkEventKey *event)
{
//return (event->state & GDK_CONTROL_MASK) && (event->keyval == GDK_KEY_F1);
return record->key == event->keyval && (event->state & record->mods);
}

static gboolean is_play_key(GdkEventKey *event)
{
// return (event->state & GDK_CONTROL_MASK) && (event->keyval == GDK_KEY_F2);
return play->key == event->keyval && (event->state & play->mods);
}



static gboolean
on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
cur_widget = widget;
GeanyDocument* doc = (GeanyDocument*)data;
guint i;
GdkEventKey** tmp = NULL;

if ((recording) && !(is_record_key(event)||is_play_key(event)))
{
GdkEventKey* new_event = g_new0(GdkEventKey, 1);
*new_event = *event;
if (recorded_size == CAPACITY)
{
tmp = g_new0(GdkEventKey*, CAPACITY * 2);
for (i = 0; i < recorded_size; i++)
tmp[i] = recorded_pattern[i];
g_free(recorded_pattern);
recorded_pattern = tmp;
CAPACITY *= 2;
}
assert(recorded_size < CAPACITY);
if (recorded_pattern[(recorded_size)] != NULL)
g_free(recorded_pattern[recorded_size]);
recorded_pattern[recorded_size++] = new_event;
}

return FALSE;
}

static void
on_document_open(GObject *obj, GeanyDocument *doc, gpointer user_data)
{
GeanyDocument *data;
ScintillaObject *sci;
g_return_if_fail(DOC_VALID(doc));
sci = doc->editor->sci;
data = g_new0(GeanyDocument, 1);
*data = *doc;
plugin_signal_connect(g_plugin, G_OBJECT(sci), "key-press-event",
FALSE, G_CALLBACK(on_key_press), data);
/* This will free the data when the sci is destroyed */
g_object_set_data_full(G_OBJECT(sci), "keyrecord-userdata", data, g_free);
}

static PluginCallback keyrecord_callbacks[] =
{
/* Set 'after' (third field) to TRUE to run the callback @a after the default handler.
* If 'after' is FALSE, the callback is run @a before the default handler, so the plugin
* can prevent Geany from processing the notification. Use this with care. */
{ "document-open", (GCallback) &on_document_open, FALSE, NULL },
{ "document-new", (GCallback) &on_document_open, FALSE, NULL },
//{ "editor-notify", (GCallback) &on_editor_notify, FALSE, NULL },
{ NULL, NULL, FALSE, NULL }
};

static void
on_record (guint key_id)
{
if (!recording)
{
recording = TRUE;
recorded_size = 0;
}
else
{
recording = FALSE;
}
}


static void
on_play (guint key_id)
{
//fprintf(stderr, "play: %d\n", key_id);
guint i;
//// sci_start_undo_action(doc->editor->sci);
if (cur_widget != NULL)
{
for (i = 0; i < (recorded_size); i++)
gdk_display_put_event(gtk_widget_get_display(cur_widget),
(GdkEvent*)(recorded_pattern[i]));

//return TRUE;
}
// sci_end_undo_action(doc->editor->sci);
}
/* Called by Geany to initialize the plugin */
static gboolean keyrecord_init(GeanyPlugin *plugin, gpointer data)
{
GeanyKeyGroup *group;

group = plugin_set_key_group (plugin, "keyrecord", 2, NULL);
record = keybindings_set_item (group, 0, on_record,
0, 0, "record", _("Start/Stop record"), NULL);
play = keybindings_set_item (group, 1, on_play,
0, 0, "play", _("Play"), NULL);

GeanyData* geany_data = plugin->geany_data;
recorded_pattern = g_new0(GdkEventKey*, CAPACITY);

guint i;
foreach_document(i) {
on_document_open(NULL, documents[i], NULL);
}
recording = FALSE;
recorded_size = 0;

geany_plugin_set_data(plugin, plugin, NULL);

g_plugin = plugin;

return TRUE;
}






/* Called by Geany before unloading the plugin.
* Here any UI changes should be removed, memory freed and any other finalization done.
* Be sure to leave Geany as it was before demo_init(). */
static void keyrecord_cleanup(GeanyPlugin *plugin, gpointer data)
{
GeanyData* geany_data = plugin->geany_data;
guint i;
for (i = 0; i < CAPACITY; i++)
if (recorded_pattern[i] != NULL) g_free(recorded_pattern[i]);
g_free(recorded_pattern);

foreach_document(i)
{
gpointer data;
ScintillaObject *sci;

sci = documents[i]->editor->sci;
data = g_object_steal_data(G_OBJECT(sci), "keyrecord-userdata");
g_free(data);
}

}

void geany_load_module(GeanyPlugin *plugin)
{
/* main_locale_init() must be called for your package before any localization can be done */
main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
plugin->info->name = _("Keystrokes recorder");
plugin->info->description = _("Allows to record some sequence of keystrokes and replay it");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs adding files to po/POTFILES.in

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thank you.

plugin->info->version = "0.1";
plugin->info->author = _("tunyash");

plugin->funcs->init = keyrecord_init;
plugin->funcs->configure = NULL;
plugin->funcs->help = NULL; /* This demo has no help but it is an option */
plugin->funcs->cleanup = keyrecord_cleanup;
plugin->funcs->callbacks = keyrecord_callbacks;

GEANY_PLUGIN_REGISTER(plugin, 225);

}