~ubuntu-branches/debian/squeeze/geany-plugins/squeeze

« back to all changes in this revision

Viewing changes to shiftcolumn/src/shiftcolumn.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2009-07-10 22:56:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090710225641-xc1126t7pq0jmpos
Tags: upstream-0.17.1
ImportĀ upstreamĀ versionĀ 0.17.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  shiftcolumn.c - a Geany plugin
 
2
 *
 
3
 *  Copyright 2009 Andrew L Janke <a.janke@gmail.com>
 
4
 *
 
5
 *  This program is free software; you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation; either version 2 of the License, or
 
8
 *  (at your option) any later version.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
18
 *  MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
 
 
22
#include "geany.h"
 
23
#include "support.h"
 
24
 
 
25
#ifdef HAVE_LOCALE_H
 
26
# include <locale.h>
 
27
#endif
 
28
 
 
29
#include "ui_utils.h"
 
30
 
 
31
#include "sciwrappers.h"
 
32
#include "document.h"
 
33
#include "keybindings.h"
 
34
#include "plugindata.h"
 
35
#include "geanyfunctions.h"
 
36
 
 
37
#include <glib.h>
 
38
#include <glib/gprintf.h>
 
39
#include <gdk/gdkkeysyms.h>
 
40
 
 
41
GeanyPlugin     *geany_plugin;
 
42
GeanyData       *geany_data;
 
43
GeanyFunctions  *geany_functions;
 
44
 
 
45
PLUGIN_VERSION_CHECK(130);
 
46
PLUGIN_SET_INFO(_("Shift Column"),
 
47
                _("Shift a selection left and right"),
 
48
                VERSION, "Andrew L Janke <a.janke@gmail.com>");
 
49
 
 
50
 
 
51
static GtkWidget *menu_item_shift_left = NULL;
 
52
static GtkWidget *menu_item_shift_right = NULL;
 
53
 
 
54
/* Keybinding(s) */
 
55
enum{
 
56
   KB_SHIFT_LEFT,
 
57
   KB_SHIFT_RIGHT,
 
58
   KB_COUNT
 
59
   };
 
60
PLUGIN_KEY_GROUP(shiftcolumn, KB_COUNT)
 
61
 
 
62
 
 
63
static void shift_left_cb(G_GNUC_UNUSED GtkMenuItem *menuitem,
 
64
                          G_GNUC_UNUSED gpointer gdata){
 
65
   gchar *txt;
 
66
   gchar *txt_i;
 
67
   gchar char_before;
 
68
   gint txt_len;
 
69
 
 
70
   gint startpos;
 
71
   gint endpos;
 
72
 
 
73
   gint startline;
 
74
   gint endline;
 
75
   gint line_iter;
 
76
   gint linepos;
 
77
   gint linelen;
 
78
 
 
79
   gint startcol;
 
80
   gint endcol;
 
81
 
 
82
   gint i;
 
83
 
 
84
   gint n_spaces;
 
85
   gchar *spaces;
 
86
 
 
87
   ScintillaObject *sci;
 
88
 
 
89
   /* get a pointer to the scintilla object */
 
90
   sci = document_get_current()->editor->sci;
 
91
 
 
92
   if (sci_has_selection(sci)){
 
93
 
 
94
      startpos = sci_get_selection_start(sci);
 
95
      endpos = sci_get_selection_end(sci);
 
96
 
 
97
      /* sanity check -- we dont care which way the block was selected */
 
98
      if(startpos > endpos){
 
99
         i = endpos;
 
100
         endpos = startpos;
 
101
         startpos = i;
 
102
         }
 
103
 
 
104
      startline = sci_get_line_from_position(sci, startpos);
 
105
      endline = sci_get_line_from_position(sci, endpos);
 
106
 
 
107
      /* normal mode */
 
108
      // if(sci_get_selection_mode(sci) == 1){
 
109
      if(startline == endline){
 
110
 
 
111
         /* get the text in question */
 
112
         txt_len = endpos - startpos;
 
113
         txt_i = g_malloc(txt_len + 1);
 
114
         txt = g_malloc(txt_len + 2);
 
115
         sci_get_selected_text(sci, txt_i);
 
116
 
 
117
         char_before = sci_get_char_at(sci, startpos - 1);
 
118
 
 
119
         /* set up new text buf */
 
120
         (void) g_sprintf(txt, "%s%c", txt_i, char_before);
 
121
 
 
122
         /* start undo */
 
123
         sci_start_undo_action(sci);
 
124
 
 
125
         /* put the new text in */
 
126
         sci_set_selection_start(sci, startpos - 1);
 
127
         sci_replace_sel(sci, txt);
 
128
 
 
129
         /* select the right bit again */
 
130
         sci_set_selection_start(sci, startpos - 1);
 
131
         sci_set_selection_end(sci, endpos - 1);
 
132
 
 
133
         /* end undo */
 
134
         sci_end_undo_action(sci);
 
135
 
 
136
         g_free(txt);
 
137
         g_free(txt_i);
 
138
         }
 
139
 
 
140
      /* rectangle mode (we hope!) */
 
141
      else{
 
142
         startcol = sci_get_col_from_position(sci, startpos);
 
143
         endcol = sci_get_col_from_position(sci, endpos);
 
144
 
 
145
         /* return early for the trivial case */
 
146
         if(startcol == 0 || startcol == endcol){
 
147
            return;
 
148
            }
 
149
 
 
150
         /* start undo */
 
151
         sci_start_undo_action(sci);
 
152
 
 
153
         for(line_iter = startline; line_iter <= endline; line_iter++){
 
154
            linepos = sci_get_position_from_line(sci, line_iter);
 
155
            linelen = sci_get_line_length(sci, line_iter);
 
156
 
 
157
            /* do we need to do something */
 
158
            if(linelen >= startcol - 1 ){
 
159
 
 
160
               /* if between the two columns */
 
161
               /* pad to the end first */
 
162
               if(linelen <= endcol){
 
163
 
 
164
                  /* bung in some spaces -- sorry, I dont like tabs */
 
165
                  n_spaces = endcol - linelen + 1;
 
166
                  spaces = g_malloc(sizeof(gchar) * (n_spaces + 1));
 
167
                  for(i = 0; i < n_spaces; i++){
 
168
                     spaces[i] = ' ';
 
169
                     }
 
170
                  spaces[i] = '\0';
 
171
 
 
172
                  sci_insert_text(sci, linepos + linelen - 1, spaces);
 
173
                  g_free(spaces);
 
174
                  }
 
175
 
 
176
               /* now move the text itself */
 
177
               sci_set_selection_mode(sci, 0);
 
178
               sci_set_selection_start(sci, linepos + startcol);
 
179
               sci_set_selection_end(sci, linepos + endcol);
 
180
 
 
181
               txt_len = sci_get_selected_text_length(sci);
 
182
               txt_i = g_malloc(txt_len + 1);
 
183
               txt = g_malloc(txt_len + 2);
 
184
 
 
185
               sci_get_selected_text(sci, txt_i);
 
186
               char_before = sci_get_char_at(sci, linepos + startcol - 1);
 
187
 
 
188
               /* set up new text buf */
 
189
               (void) g_sprintf(txt, "%s%c", txt_i, char_before);
 
190
 
 
191
               /* put the new text in */
 
192
               sci_set_selection_start(sci, linepos + startcol - 1);
 
193
               sci_replace_sel(sci, txt);
 
194
 
 
195
               g_free(txt);
 
196
               g_free(txt_i);
 
197
               }
 
198
            }
 
199
 
 
200
         /* put the selection box back */
 
201
         /* here we rely upon the last result of linepos */
 
202
         sci_set_selection_mode(sci, 1);
 
203
         sci_set_selection_start(sci, startpos - 1);
 
204
         sci_set_selection_end(sci, linepos + endcol - 1);
 
205
 
 
206
         /* end undo action */
 
207
         sci_end_undo_action(sci);
 
208
         }
 
209
 
 
210
      }
 
211
   }
 
212
 
 
213
static void shift_right_cb(G_GNUC_UNUSED GtkMenuItem *menuitem,
 
214
                           G_GNUC_UNUSED gpointer gdata){
 
215
   gchar *txt;
 
216
   gchar *txt_i;
 
217
   gchar char_after;
 
218
   gint txt_len;
 
219
 
 
220
   gint startpos;
 
221
   gint endpos;
 
222
 
 
223
   gint startline;
 
224
   gint endline;
 
225
   gint line_iter;
 
226
   gint linepos;
 
227
   gint linelen;
 
228
 
 
229
   gint startcol;
 
230
   gint endcol;
 
231
 
 
232
   gint i;
 
233
 
 
234
   ScintillaObject *sci;
 
235
 
 
236
   /* get a pointer to the scintilla object */
 
237
   sci = document_get_current()->editor->sci;
 
238
 
 
239
   if (sci_has_selection(sci)){
 
240
 
 
241
      startpos = sci_get_selection_start(sci);
 
242
      endpos = sci_get_selection_end(sci);
 
243
 
 
244
      /* sanity check -- we dont care which way the block was selected */
 
245
      if(startpos > endpos){
 
246
         i = endpos;
 
247
         endpos = startpos;
 
248
         startpos = i;
 
249
         }
 
250
 
 
251
      startline = sci_get_line_from_position(sci, startpos);
 
252
      endline = sci_get_line_from_position(sci, endpos);
 
253
 
 
254
      /* normal mode */
 
255
      if(startline == endline){
 
256
 
 
257
         /* get the text in question */
 
258
         txt_len = endpos - startpos;
 
259
         txt_i = g_malloc(txt_len + 1);
 
260
         txt = g_malloc(txt_len + 2);
 
261
         sci_get_selected_text(sci, txt_i);
 
262
 
 
263
         char_after = sci_get_char_at(sci, endpos);
 
264
 
 
265
         /* set up new text buf */
 
266
         (void) g_sprintf(txt, "%c%s", char_after, txt_i);
 
267
 
 
268
         /* start undo */
 
269
         sci_start_undo_action(sci);
 
270
 
 
271
         /* put the new text in */
 
272
         sci_set_selection_end(sci, endpos + 1);
 
273
         sci_replace_sel(sci, txt);
 
274
 
 
275
         /* select the right bit again */
 
276
         sci_set_selection_start(sci, startpos + 1);
 
277
         sci_set_selection_end(sci, endpos + 1);
 
278
 
 
279
         /* end undo */
 
280
         sci_end_undo_action(sci);
 
281
 
 
282
         g_free(txt);
 
283
         g_free(txt_i);
 
284
         }
 
285
 
 
286
      /* rectangle mode (we hope!) */
 
287
      else{
 
288
         startcol = sci_get_col_from_position(sci, startpos);
 
289
         endcol = sci_get_col_from_position(sci, endpos);
 
290
 
 
291
         /* start undo */
 
292
         sci_start_undo_action(sci);
 
293
 
 
294
         for(line_iter = startline; line_iter <= endline; line_iter++){
 
295
            linepos = sci_get_position_from_line(sci, line_iter);
 
296
            linelen = sci_get_line_length(sci, line_iter);
 
297
 
 
298
            /* do we need to do something */
 
299
            if(linelen >= startcol - 1 ){
 
300
 
 
301
               /* if between the two columns or at the end */
 
302
               /* add in a space */
 
303
               if(linelen <= endcol || linelen - 1 == endcol){
 
304
                  txt = g_malloc(sizeof(gchar) * 2);
 
305
                  sprintf(txt, " ");
 
306
 
 
307
                  sci_insert_text(sci, linepos + startcol, txt);
 
308
                  g_free(txt);
 
309
                  }
 
310
 
 
311
               else{
 
312
                  /* move the text itself */
 
313
                  sci_set_selection_mode(sci, 0);
 
314
                  sci_set_selection_start(sci, linepos + startcol);
 
315
                  sci_set_selection_end(sci, linepos + endcol);
 
316
 
 
317
                  txt_len = sci_get_selected_text_length(sci);
 
318
                  txt_i = g_malloc(txt_len + 1);
 
319
                  txt = g_malloc(txt_len + 2);
 
320
 
 
321
                  sci_get_selected_text(sci, txt_i);
 
322
                  char_after = sci_get_char_at(sci, linepos + endcol);
 
323
 
 
324
                  /* set up new text buf */
 
325
                  (void) g_sprintf(txt, "%c%s", char_after, txt_i);
 
326
 
 
327
                  /* put the new text in */
 
328
                  sci_set_selection_end(sci, linepos + endcol + 1);
 
329
                  sci_replace_sel(sci, txt);
 
330
 
 
331
                  g_free(txt);
 
332
                  g_free(txt_i);
 
333
                  }
 
334
               }
 
335
            }
 
336
 
 
337
         /* put the selection box back */
 
338
         /* here we rely upon the last result of linepos */
 
339
         sci_set_selection_mode(sci, 1);
 
340
         sci_set_selection_start(sci, startpos + 1);
 
341
         sci_set_selection_end(sci, linepos + endcol + 1);
 
342
 
 
343
         /* end undo action */
 
344
         sci_end_undo_action(sci);
 
345
         }
 
346
      }
 
347
   }
 
348
 
 
349
 
 
350
static void kb_shift_left(G_GNUC_UNUSED guint key_id){
 
351
   
 
352
   /* sanity check */
 
353
   if (document_get_current() == NULL){
 
354
       return;
 
355
       }
 
356
   
 
357
   shift_left_cb(NULL, NULL);
 
358
   }
 
359
 
 
360
static void kb_shift_right(G_GNUC_UNUSED guint key_id){
 
361
   
 
362
   /* sanity check */
 
363
   if (document_get_current() == NULL){
 
364
       return;
 
365
       }
 
366
   
 
367
   shift_right_cb(NULL, NULL);
 
368
   }
 
369
 
 
370
void plugin_init(G_GNUC_UNUSED GeanyData *data){
 
371
 
 
372
   /* init gettext and friends */
 
373
   main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
 
374
 
 
375
   menu_item_shift_left = gtk_menu_item_new_with_mnemonic(_("Shift Left"));
 
376
   gtk_widget_show(menu_item_shift_left);
 
377
   gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
 
378
       menu_item_shift_left);
 
379
   g_signal_connect(menu_item_shift_left, "activate",
 
380
       G_CALLBACK(shift_left_cb), NULL);
 
381
 
 
382
   menu_item_shift_right = gtk_menu_item_new_with_mnemonic(_("Shift Right"));
 
383
   gtk_widget_show(menu_item_shift_right);
 
384
   gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
 
385
       menu_item_shift_right);
 
386
   g_signal_connect(menu_item_shift_right, "activate",
 
387
       G_CALLBACK(shift_right_cb), NULL);
 
388
   
 
389
   /* make sure our menu items aren't called when there is no doc open */
 
390
   ui_add_document_sensitive(menu_item_shift_right);
 
391
   ui_add_document_sensitive(menu_item_shift_left);
 
392
 
 
393
   /* setup keybindings */
 
394
   keybindings_set_item(plugin_key_group, KB_SHIFT_LEFT, kb_shift_left,
 
395
      GDK_9, GDK_CONTROL_MASK, "shift_left", _("Shift Left"), menu_item_shift_left);
 
396
   keybindings_set_item(plugin_key_group, KB_SHIFT_RIGHT, kb_shift_right,
 
397
      GDK_0, GDK_CONTROL_MASK, "shift_right", _("Shift Right"), menu_item_shift_right);
 
398
   }
 
399
 
 
400
void plugin_cleanup(void){
 
401
   gtk_widget_destroy(menu_item_shift_left);
 
402
   gtk_widget_destroy(menu_item_shift_right);
 
403
   }