2 (c) 2009 by Leon Winter
3 (c) 2009, 2010 by Hannes Schueller
4 (c) 2009, 2010 by Matto Fransen
5 (c) 2010 by Hans-Peter Deifel
6 (c) 2010 by Thomas Adam
11 #include "vimprobable.h"
13 #include "utilities.h"
15 extern char commandhistory
[COMMANDHISTSIZE
][255];
16 extern Command
*commands
;
17 extern int lastcommand
, maxcommands
, commandpointer
;
18 extern KeyList
*keylistroot
;
20 extern char *error_msg
;
21 extern gboolean complete_case_sensitive
;
23 gboolean
read_rcfile(const char *config
)
28 gboolean returnval
= TRUE
;
30 if ((fpin
= fopen(config
, "r")) == NULL
)
32 while (fgets(s
, 254, fpin
)) {
34 * ignore lines that begin with #, / and such
47 void save_command_history(char *line
)
52 while (isspace(*c
) && *c
)
56 strncpy(commandhistory
[lastcommand
], c
, 254);
58 if (maxcommands
< COMMANDHISTSIZE
- 1)
60 if (lastcommand
== COMMANDHISTSIZE
)
62 commandpointer
= lastcommand
;
66 process_save_qmark(const char *bm
, WebKitWebView
*webview
)
70 const char *uri
= webkit_web_view_get_uri(webview
);
77 if ( mark
< 1 || mark
> 9 )
80 a
.s
= g_strdup_printf("Invalid quickmark, only 1-9");
84 if ( uri
== NULL
) return FALSE
;
85 for( i
=0; i
< 9; ++i
) strcpy( qmarks
[i
], "");
87 filename
= g_strdup_printf(QUICKMARK_FILE
);
89 /* get current quickmarks */
91 fp
= fopen(filename
, "r");
93 for( i
=0; i
< 10; ++i
) {
99 while (buf
[l
] && l
< 100 && buf
[l
] != '\n') {
108 /* save quickmarks */
109 strcpy( qmarks
[mark
-1], uri
);
110 fp
= fopen(filename
, "w");
111 if (fp
== NULL
) return FALSE
;
112 for( i
=0; i
< 10; ++i
)
113 fprintf(fp
, "%s\n", qmarks
[i
]);
116 a
.s
= g_strdup_printf("Saved as quickmark %d: %s", mark
, uri
);
126 KeyList
*ptr
, *current
;
131 while ( keys
[i
].key
!= 0 )
133 current
= malloc(sizeof(KeyList
));
134 if (current
== NULL
) {
135 printf("Not enough memory\n");
138 current
->Element
= keys
[i
];
139 current
->next
= NULL
;
140 if (keylistroot
== NULL
) keylistroot
= current
;
141 if (ptr
!= NULL
) ptr
->next
= current
;
148 parse_colour(char *color
) {
152 colorlen
= (int)strlen(color
);
157 /* help the user a bit by making string like
158 #a10 and strings like ffffff full 6digit
159 strings with # in front :)
162 if (color
[0] == '#') {
165 strncpy(goodcolor
, color
, 7);
168 goodcolor
[1] = color
[1];
169 goodcolor
[2] = color
[1];
170 goodcolor
[3] = color
[2];
171 goodcolor
[4] = color
[2];
172 goodcolor
[5] = color
[3];
173 goodcolor
[6] = color
[3];
176 goodcolor
[1] = color
[1];
177 goodcolor
[2] = color
[1];
178 goodcolor
[3] = color
[1];
179 goodcolor
[4] = color
[1];
180 goodcolor
[5] = color
[1];
181 goodcolor
[6] = color
[1];
187 strncpy(&goodcolor
[1], color
, 6);
190 goodcolor
[1] = color
[0];
191 goodcolor
[2] = color
[0];
192 goodcolor
[3] = color
[1];
193 goodcolor
[4] = color
[1];
194 goodcolor
[5] = color
[2];
195 goodcolor
[6] = color
[2];
198 goodcolor
[1] = color
[0];
199 goodcolor
[2] = color
[0];
200 goodcolor
[3] = color
[0];
201 goodcolor
[4] = color
[0];
202 goodcolor
[5] = color
[0];
203 goodcolor
[6] = color
[0];
208 if (strlen (goodcolor
) != 7) {
211 strncpy(color
, goodcolor
, 8);
217 changemapping(Key
* search_key
, int maprecord
) {
218 KeyList
*current
, *newkey
;
220 current
= keylistroot
;
223 while (current
->next
!= NULL
) {
225 current
->Element
.mask
== search_key
->mask
&&
226 current
->Element
.modkey
== search_key
->modkey
&&
227 current
->Element
.key
== search_key
->key
229 current
->Element
.func
= commands
[maprecord
].func
;
230 current
->Element
.arg
= commands
[maprecord
].arg
;
233 current
= current
->next
;
235 newkey
= malloc(sizeof(KeyList
));
236 if (newkey
== NULL
) {
237 printf("Not enough memory\n");
240 newkey
->Element
.mask
= search_key
->mask
;
241 newkey
->Element
.modkey
= search_key
->modkey
;
242 newkey
->Element
.key
= search_key
->key
;
243 newkey
->Element
.func
= commands
[maprecord
].func
;
244 newkey
->Element
.arg
= commands
[maprecord
].arg
;
247 if (keylistroot
== NULL
) keylistroot
= newkey
;
249 if (current
!= NULL
) current
->next
= newkey
;
255 mappings(const Arg
*arg
) {
259 set_error("Missing argument.");
262 strncpy(line
, arg
->s
, 254);
263 if (process_map_line(line
))
266 set_error("Invalid mapping.");
272 process_mapping(char * keystring
, int maprecord
) {
276 search_key
.modkey
= 0;
279 if (strlen(keystring
) == 1) {
280 search_key
.key
= keystring
[0];
283 if (strlen(keystring
) == 2) {
284 search_key
.modkey
= keystring
[0];
285 search_key
.key
= keystring
[1];
288 /* process stuff like <S-v> for Shift-v or <C-v> for Ctrl-v
289 or stuff like <S-v>a for Shift-v,a or <C-v>a for Ctrl-v,a
291 if ((strlen(keystring
) == 5 || strlen(keystring
) == 6) && keystring
[0] == '<' && keystring
[4] == '>') {
292 switch (toupper(keystring
[1])) {
294 search_key
.mask
= GDK_SHIFT_MASK
;
295 if (strlen(keystring
) == 5) {
296 keystring
[3] = toupper(keystring
[3]);
298 keystring
[3] = tolower(keystring
[3]);
299 keystring
[5] = toupper(keystring
[5]);
303 search_key
.mask
= GDK_CONTROL_MASK
;
306 if (!search_key
.mask
)
308 if (strlen(keystring
) == 5) {
309 search_key
.key
= keystring
[3];
311 search_key
.modkey
= keystring
[3];
312 search_key
.key
= keystring
[5];
316 /* process stuff like <S-v> for Shift-v or <C-v> for Ctrl-v
317 or stuff like a<S-v> for a,Shift-v or a<C-v> for a,Ctrl-v
319 if (strlen(keystring
) == 6 && keystring
[1] == '<' && keystring
[5] == '>') {
320 switch (toupper(keystring
[2])) {
322 search_key
.mask
= GDK_SHIFT_MASK
;
323 keystring
[4] = toupper(keystring
[4]);
326 search_key
.mask
= GDK_CONTROL_MASK
;
329 if (!search_key
.mask
)
331 search_key
.modkey
= keystring
[0];
332 search_key
.key
= keystring
[4];
334 return (changemapping(&search_key
, maprecord
));
338 process_map_line(char *line
) {
344 if (!strlen (my_pair
.what
))
346 while (isspace (*c
) && *c
)
349 if (*c
== ':' || *c
== '=')
353 if (!strlen (my_pair
.value
))
355 listlen
= LENGTH(commands
);
356 for (i
= 0; i
< listlen
; i
++) {
357 if (strlen(commands
[i
].cmd
) == strlen(my_pair
.value
) && strncmp(commands
[i
].cmd
, my_pair
.value
, strlen(my_pair
.value
)) == 0)
358 return process_mapping(my_pair
.what
, i
);
364 build_taglist(const Arg
*arg
, FILE *f
) {
365 int k
= 0, in_tag
= 0;
366 int t
= 0, marker
= 0;
367 char foundtab
[MAXTAGSIZE
+1];
369 if (!isspace(arg
->s
[k
]) && !in_tag
) {
373 if (isspace(arg
->s
[k
]) && in_tag
) {
376 while (marker
< k
&& t
< MAXTAGSIZE
) foundtab
[t
++] = arg
->s
[marker
++];
378 fprintf(f
, " [%s]", foundtab
);
384 while (marker
< strlen(arg
->s
) && t
< MAXTAGSIZE
) foundtab
[t
++] = arg
->s
[marker
++];
386 fprintf(f
, " [%s]", foundtab
);
392 set_error(const char *error
) {
393 /* it should never happen that set_error is called more than once,
394 * but to avoid any potential memory leaks, we ignore any subsequent
395 * error if the current one has not been shown */
396 if (error_msg
== NULL
) {
397 error_msg
= g_strdup_printf("%s", error
);
402 give_feedback(const char *feedback
)
404 Arg a
= { .i
= Info
};
406 a
.s
= g_strdup_printf(feedback
);
411 complete_list(const char *searchfor
, const int mode
, Listelement
*elementlist
)
414 const char *filename
;
415 Listelement
*candidatelist
= NULL
, *candidatepointer
= NULL
;
416 char s
[255] = "", readelement
[MAXTAGSIZE
+ 1] = "";
420 /* open in history file */
421 filename
= g_strdup_printf(HISTORY_STORAGE_FILENAME
);
423 /* open in bookmark file (for tags and bookmarks) */
424 filename
= g_strdup_printf(BOOKMARKS_STORAGE_FILENAME
);
426 f
= fopen(filename
, "r");
428 g_free((gpointer
)filename
);
432 while (fgets(s
, 254, f
)) {
434 /* just tags (could be more than one per line) */
436 while (s
[i
] && i
< 254) {
437 while (s
[i
] != '[' && s
[i
])
443 while (s
[i
] != ']' && s
[i
] && t
< MAXTAGSIZE
)
444 readelement
[t
++] = s
[i
++];
445 readelement
[t
] = '\0';
446 candidatelist
= add_list(readelement
, candidatelist
);
450 /* complete string (bookmarks & history) */
451 candidatelist
= add_list(s
, candidatelist
);
453 candidatepointer
= candidatelist
;
454 while (candidatepointer
!= NULL
) {
455 if (!complete_case_sensitive
) {
456 g_strdown(candidatepointer
->element
);
458 if (!strlen(searchfor
) || strstr(candidatepointer
->element
, searchfor
) != NULL
) {
459 /* only use string up to the first space */
460 memset(readelement
, 0, MAXTAGSIZE
+ 1);
461 if (strchr(candidatepointer
->element
, ' ') != NULL
) {
462 i
= strcspn(candidatepointer
->element
, " ");
463 strncpy(readelement
, candidatepointer
->element
, i
);
465 strncpy(readelement
, candidatepointer
->element
, MAXTAGSIZE
);
467 elementlist
= add_list(readelement
, elementlist
);
468 n
= count_list(elementlist
);
470 if (n
>= MAX_LIST_SIZE
)
472 candidatepointer
= candidatepointer
->next
;
474 free_list(candidatelist
);
475 candidatelist
= NULL
;
476 if (n
>= MAX_LIST_SIZE
)
479 g_free((gpointer
)filename
);
480 return (elementlist
);
484 add_list(const char *element
, Listelement
*elementlist
)
487 Listelement
*newelement
, *elementpointer
, *lastelement
;
489 if (elementlist
== NULL
) { /* first element */
490 newelement
= malloc(sizeof(Listelement
));
491 if (newelement
== NULL
)
493 strncpy(newelement
->element
, element
, 254);
494 newelement
->next
= NULL
;
497 elementpointer
= elementlist
;
500 /* check if element is already in list */
501 while (elementpointer
!= NULL
) {
502 if (strlen(elementpointer
->element
) == n
&&
503 strncmp(elementpointer
->element
, element
, n
) == 0)
504 return (elementlist
);
505 lastelement
= elementpointer
;
506 elementpointer
= elementpointer
->next
;
510 newelement
= malloc(sizeof(Listelement
));
511 if (newelement
== NULL
)
513 lastelement
->next
= newelement
;
514 strncpy(newelement
->element
, element
, 254);
515 newelement
->next
= NULL
;
520 free_list(Listelement
*elementlist
)
522 Listelement
*elementpointer
;
524 while (elementlist
!= NULL
) {
525 elementpointer
= elementlist
->next
;
527 elementlist
= elementpointer
;
532 count_list(Listelement
*elementlist
)
534 Listelement
*elementpointer
= elementlist
;
537 while (elementpointer
!= NULL
) {
539 elementpointer
= elementpointer
->next
;