1 /* Widgets for the Midnight Commander
3 Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
6 Authors: 1994, 1995 Radek Doulik
7 1994, 1995 Miguel de Icaza
11 2009, 2010 Andrew Borodin
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 * \brief Source: WInput widget
36 #include <sys/types.h>
40 #include "lib/global.h"
42 #include "lib/tty/tty.h"
43 #include "lib/tty/mouse.h"
44 #include "lib/tty/key.h" /* XCTRL and ALT macros */
45 #include "lib/vfs/mc-vfs/vfs.h"
46 #include "lib/fileloc.h"
48 #include "lib/strutil.h"
50 #include "lib/keybind.h" /* global_keymap_t */
51 #include "lib/widget.h"
53 #include "src/main.h" /* home_dir */
54 #include "src/filemanager/midnight.h" /* current_panel */
55 #include "src/clipboard.h" /* copy_file_to_ext_clip, paste_to_file_from_ext_clip */
56 #include "src/keybind-defaults.h" /* input_map */
58 /*** global variables ****************************************************************************/
62 /*** file scope macro definitions ****************************************************************/
64 #define LARGE_HISTORY_BUTTON 1
66 #ifdef LARGE_HISTORY_BUTTON
67 #define HISTORY_BUTTON_WIDTH 3
69 #define HISTORY_BUTTON_WIDTH 1
72 #define should_show_history_button(in) \
73 (in->history != NULL && in->field_width > HISTORY_BUTTON_WIDTH * 2 + 1 \
74 && in->widget.owner != NULL)
76 /*** file scope type declarations ****************************************************************/
78 /*** file scope variables ************************************************************************/
80 /* Input widgets have a global kill ring */
81 /* Pointer to killed data */
82 static char *kill_buffer
= NULL
;
84 /*** file scope functions ************************************************************************/
87 save_text_to_clip_file (const char *text
)
94 fname
= g_build_filename (home_dir
, EDIT_CLIP_FILE
, NULL
);
95 file
= mc_open (fname
, O_CREAT
| O_WRONLY
| O_TRUNC
,
96 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
);
102 str_len
= strlen (text
);
103 ret
= mc_write (file
, (char *) text
, str_len
);
105 return ret
== (ssize_t
) str_len
;
108 /* --------------------------------------------------------------------------------------------- */
111 load_text_from_clip_file (char **text
)
116 gboolean first
= TRUE
;
118 fname
= g_build_filename (home_dir
, EDIT_CLIP_FILE
, NULL
);
119 f
= fopen (fname
, "r");
127 while (fgets (buf
, sizeof (buf
), f
))
134 if (buf
[len
- 1] == '\n')
140 *text
= g_strdup (buf
);
144 /* remove \n on EOL */
147 tmp
= g_strconcat (*text
, " ", buf
, (char *) NULL
);
156 return (*text
!= NULL
);
159 /* --------------------------------------------------------------------------------------------- */
162 panel_save_curent_file_to_clip_file (void)
164 gboolean res
= FALSE
;
166 if (current_panel
->marked
== 0)
167 res
= save_text_to_clip_file (selection (current_panel
)->fname
);
171 gboolean first
= TRUE
;
174 for (i
= 0; i
< current_panel
->count
; i
++)
175 if (current_panel
->dir
.list
[i
].f
.marked
!= 0)
176 { /* Skip the unmarked ones */
179 flist
= g_strdup (current_panel
->dir
.list
[i
].fname
);
184 /* Add empty lines after the file */
188 g_strconcat (flist
, "\n", current_panel
->dir
.list
[i
].fname
, (char *) NULL
);
196 res
= save_text_to_clip_file (flist
);
203 /* --------------------------------------------------------------------------------------------- */
206 draw_history_button (WInput
* in
)
209 gboolean disabled
= (((Widget
*) in
)->options
& W_DISABLED
) != 0;
211 c
= in
->history
->next
? (in
->history
->prev
? '|' : 'v') : '^';
212 widget_move (&in
->widget
, 0, in
->field_width
- HISTORY_BUTTON_WIDTH
);
213 tty_setcolor (disabled
? DISABLED_COLOR
: in
->color
[WINPUTC_HISTORY
]);
214 #ifdef LARGE_HISTORY_BUTTON
217 h
= in
->widget
.owner
;
218 tty_print_string ("[ ]");
219 widget_move (&in
->widget
, 0, in
->field_width
- HISTORY_BUTTON_WIDTH
+ 1);
225 /* --------------------------------------------------------------------------------------------- */
228 input_set_markers (WInput
* in
, long m1
)
233 /* --------------------------------------------------------------------------------------------- */
236 input_mark_cmd (WInput
* in
, gboolean mark
)
240 in
->highlight
= FALSE
;
241 input_set_markers (in
, 0);
245 in
->highlight
= TRUE
;
246 input_set_markers (in
, in
->point
);
250 /* --------------------------------------------------------------------------------------------- */
253 input_eval_marks (WInput
* in
, long *start_mark
, long *end_mark
)
257 *start_mark
= min (in
->mark
, in
->point
);
258 *end_mark
= max (in
->mark
, in
->point
);
263 *start_mark
= *end_mark
= 0;
268 /* --------------------------------------------------------------------------------------------- */
271 delete_region (WInput
* in
, int x_first
, int x_last
)
273 int first
= min (x_first
, x_last
);
274 int last
= max (x_first
, x_last
);
277 input_mark_cmd (in
, FALSE
);
279 last
= str_offset_to_pos (in
->buffer
, last
);
280 first
= str_offset_to_pos (in
->buffer
, first
);
281 len
= strlen (&in
->buffer
[last
]) + 1;
282 memmove (&in
->buffer
[first
], &in
->buffer
[last
], len
);
284 in
->need_push
= TRUE
;
287 /* --------------------------------------------------------------------------------------------- */
290 do_show_hist (WInput
* in
)
294 r
= history_show (&in
->history
, &in
->widget
);
297 input_assign_text (in
, r
);
302 /* --------------------------------------------------------------------------------------------- */
305 push_history (WInput
* in
, const char *text
)
307 /* input widget where urls with passwords are entered without any
309 const char *password_input_fields
[] = {
310 " Link to a remote machine ",
312 " SMB link to machine "
314 const size_t ELEMENTS
= (sizeof (password_input_fields
) / sizeof (password_input_fields
[0]));
324 for (i
= 0; i
< ELEMENTS
; i
++)
325 password_input_fields
[i
] = _(password_input_fields
[i
]);
328 t
= g_strstrip (g_strdup (text
));
331 t
= g_strdup (empty
? "" : text
);
333 if (in
->history_name
!= NULL
)
335 /* FIXME: It is the strange code. Rewrite is needed. */
337 const char *p
= in
->history_name
+ 3;
339 for (i
= 0; i
< ELEMENTS
; i
++)
340 if (strcmp (p
, password_input_fields
[i
]) == 0)
343 strip_password (t
, i
>= ELEMENTS
);
346 in
->history
= list_append_unique (in
->history
, t
);
347 in
->need_push
= FALSE
;
350 /* --------------------------------------------------------------------------------------------- */
353 move_buffer_backward (WInput
* in
, int start
, int end
)
358 str_len
= str_length (in
->buffer
);
359 if (start
>= str_len
|| end
> str_len
+ 1)
362 pos
= str_offset_to_pos (in
->buffer
, start
);
363 len
= str_offset_to_pos (in
->buffer
, end
) - pos
;
365 for (i
= pos
; in
->buffer
[i
+ len
- 1]; i
++)
366 in
->buffer
[i
] = in
->buffer
[i
+ len
];
369 /* --------------------------------------------------------------------------------------------- */
372 insert_char (WInput
* in
, int c_code
)
380 if (input_eval_marks (in
, &m1
, &m2
))
381 delete_region (in
, m1
, m2
);
384 return MSG_NOT_HANDLED
;
386 if (in
->charpoint
>= MB_LEN_MAX
)
389 in
->charbuf
[in
->charpoint
] = c_code
;
392 res
= str_is_valid_char (in
->charbuf
, in
->charpoint
);
396 in
->charpoint
= 0; /* broken multibyte char, skip */
400 in
->need_push
= TRUE
;
401 if (strlen (in
->buffer
) + 1 + in
->charpoint
>= in
->current_max_size
)
403 /* Expand the buffer */
404 size_t new_length
= in
->current_max_size
+ in
->field_width
+ in
->charpoint
;
405 char *narea
= g_try_renew (char, in
->buffer
, new_length
);
409 in
->current_max_size
= new_length
;
413 if (strlen (in
->buffer
) + in
->charpoint
< in
->current_max_size
)
415 /* bytes from begin */
416 size_t ins_point
= str_offset_to_pos (in
->buffer
, in
->point
);
418 size_t rest_bytes
= strlen (in
->buffer
+ ins_point
);
420 for (i
= rest_bytes
+ 1; i
> 0; i
--)
421 in
->buffer
[ins_point
+ i
+ in
->charpoint
- 1] = in
->buffer
[ins_point
+ i
- 1];
423 memcpy (in
->buffer
+ ins_point
, in
->charbuf
, in
->charpoint
);
431 /* --------------------------------------------------------------------------------------------- */
434 beginning_of_line (WInput
* in
)
440 /* --------------------------------------------------------------------------------------------- */
443 end_of_line (WInput
* in
)
445 in
->point
= str_length (in
->buffer
);
449 /* --------------------------------------------------------------------------------------------- */
452 backward_char (WInput
* in
)
456 act
= in
->buffer
+ str_offset_to_pos (in
->buffer
, in
->point
);
458 in
->point
-= str_cprev_noncomb_char (&act
, in
->buffer
);
462 /* --------------------------------------------------------------------------------------------- */
465 forward_char (WInput
* in
)
469 act
= in
->buffer
+ str_offset_to_pos (in
->buffer
, in
->point
);
471 in
->point
+= str_cnext_noncomb_char (&act
);
475 /* --------------------------------------------------------------------------------------------- */
478 forward_word (WInput
* in
)
482 p
= in
->buffer
+ str_offset_to_pos (in
->buffer
, in
->point
);
483 while (p
[0] != '\0' && (str_isspace (p
) || str_ispunct (p
)))
488 while (p
[0] != '\0' && !str_isspace (p
) && !str_ispunct (p
))
495 /* --------------------------------------------------------------------------------------------- */
498 backward_word (WInput
* in
)
500 const char *p
, *p_tmp
;
502 for (p
= in
->buffer
+ str_offset_to_pos (in
->buffer
, in
->point
);
503 (p
!= in
->buffer
) && (p
[0] == '\0'); str_cprev_char (&p
), in
->point
--);
505 while (p
!= in
->buffer
)
509 if (!str_isspace (p
) && !str_ispunct (p
))
516 while (p
!= in
->buffer
)
519 if (str_isspace (p
) || str_ispunct (p
))
526 /* --------------------------------------------------------------------------------------------- */
529 backward_delete (WInput
* in
)
531 const char *act
= in
->buffer
+ str_offset_to_pos (in
->buffer
, in
->point
);
537 start
= in
->point
- str_cprev_noncomb_char (&act
, in
->buffer
);
538 move_buffer_backward (in
, start
, in
->point
);
540 in
->need_push
= TRUE
;
544 /* --------------------------------------------------------------------------------------------- */
547 delete_char (WInput
* in
)
552 act
= in
->buffer
+ str_offset_to_pos (in
->buffer
, in
->point
);
553 end
+= str_cnext_noncomb_char (&act
);
555 move_buffer_backward (in
, in
->point
, end
);
557 in
->need_push
= TRUE
;
560 /* --------------------------------------------------------------------------------------------- */
563 copy_region (WInput
* in
, int x_first
, int x_last
)
565 int first
= min (x_first
, x_last
);
566 int last
= max (x_first
, x_last
);
570 /* Copy selected files to clipboard */
571 panel_save_curent_file_to_clip_file ();
572 /* try use external clipboard utility */
573 copy_file_to_ext_clip ();
577 g_free (kill_buffer
);
579 first
= str_offset_to_pos (in
->buffer
, first
);
580 last
= str_offset_to_pos (in
->buffer
, last
);
582 kill_buffer
= g_strndup (in
->buffer
+ first
, last
- first
);
584 save_text_to_clip_file (kill_buffer
);
585 /* try use external clipboard utility */
586 copy_file_to_ext_clip ();
589 /* --------------------------------------------------------------------------------------------- */
592 kill_word (WInput
* in
)
594 int old_point
= in
->point
;
598 new_point
= in
->point
;
599 in
->point
= old_point
;
601 delete_region (in
, old_point
, new_point
);
602 in
->need_push
= TRUE
;
606 /* --------------------------------------------------------------------------------------------- */
609 back_kill_word (WInput
* in
)
611 int old_point
= in
->point
;
615 new_point
= in
->point
;
616 in
->point
= old_point
;
618 delete_region (in
, old_point
, new_point
);
619 in
->need_push
= TRUE
;
622 /* --------------------------------------------------------------------------------------------- */
627 if (kill_buffer
!= NULL
)
632 for (p
= kill_buffer
; *p
!= '\0'; p
++)
633 insert_char (in
, *p
);
638 /* --------------------------------------------------------------------------------------------- */
641 kill_line (WInput
* in
)
645 chp
= str_offset_to_pos (in
->buffer
, in
->point
);
646 g_free (kill_buffer
);
647 kill_buffer
= g_strdup (&in
->buffer
[chp
]);
648 in
->buffer
[chp
] = '\0';
652 /* --------------------------------------------------------------------------------------------- */
655 clear_line (WInput
* in
)
658 in
->buffer
[0] = '\0';
661 in
->highlight
= FALSE
;
666 ins_from_clip (WInput
* in
)
670 /* try use external clipboard utility */
671 paste_to_file_from_ext_clip ();
673 if (load_text_from_clip_file (&p
))
677 for (pp
= p
; *pp
!= '\0'; pp
++)
678 insert_char (in
, *pp
);
684 /* --------------------------------------------------------------------------------------------- */
687 hist_prev (WInput
* in
)
691 if (in
->history
== NULL
)
695 push_history (in
, in
->buffer
);
697 prev
= g_list_previous (in
->history
);
701 input_assign_text (in
, (char *) prev
->data
);
702 in
->need_push
= FALSE
;
706 /* --------------------------------------------------------------------------------------------- */
709 hist_next (WInput
* in
)
713 push_history (in
, in
->buffer
);
714 input_assign_text (in
, "");
718 if (in
->history
== NULL
)
721 if (in
->history
->next
== NULL
)
722 input_assign_text (in
, "");
725 in
->history
= g_list_next (in
->history
);
726 input_assign_text (in
, (char *) in
->history
->data
);
727 in
->need_push
= FALSE
;
731 /* --------------------------------------------------------------------------------------------- */
734 port_region_marked_for_delete (WInput
* in
)
736 in
->buffer
[0] = '\0';
742 /* --------------------------------------------------------------------------------------------- */
745 input_execute_cmd (WInput
* in
, unsigned long command
)
747 cb_ret_t res
= MSG_HANDLED
;
749 /* a highlight command like shift-arrow */
750 if (command
== CK_InputLeftHighlight
||
751 command
== CK_InputRightHighlight
||
752 command
== CK_InputWordLeftHighlight
||
753 command
== CK_InputWordRightHighlight
||
754 command
== CK_InputBolHighlight
|| command
== CK_InputEolHighlight
)
758 input_mark_cmd (in
, FALSE
); /* clear */
759 input_mark_cmd (in
, TRUE
); /* marking on */
765 case CK_InputForwardWord
:
766 case CK_InputBackwardWord
:
767 case CK_InputForwardChar
:
768 case CK_InputBackwardChar
:
770 input_mark_cmd (in
, FALSE
);
776 case CK_InputBolHighlight
:
777 beginning_of_line (in
);
780 case CK_InputEolHighlight
:
783 case CK_InputMoveLeft
:
784 case CK_InputLeftHighlight
:
787 case CK_InputWordLeft
:
788 case CK_InputWordLeftHighlight
:
791 case CK_InputMoveRight
:
792 case CK_InputRightHighlight
:
795 case CK_InputWordRight
:
796 case CK_InputWordRightHighlight
:
799 case CK_InputBackwardChar
:
802 case CK_InputBackwardWord
:
805 case CK_InputForwardChar
:
808 case CK_InputForwardWord
:
811 case CK_InputBackwardDelete
:
815 if (input_eval_marks (in
, &m1
, &m2
))
816 delete_region (in
, m1
, m2
);
819 backward_delete (in
);
821 case CK_InputDeleteChar
:
823 port_region_marked_for_delete (in
);
824 else if (in
->highlight
)
827 if (input_eval_marks (in
, &m1
, &m2
))
828 delete_region (in
, m1
, m2
);
833 case CK_InputKillWord
:
836 case CK_InputBackwardKillWord
:
839 case CK_InputSetMark
:
840 input_mark_cmd (in
, TRUE
);
842 case CK_InputKillRegion
:
843 delete_region (in
, in
->point
, in
->mark
);
845 case CK_InputKillLine
:
846 /* clear command line from cursor to the EOL */
849 case CK_InputClearLine
:
850 /* clear command line */
853 case CK_InputCopyRegion
:
854 copy_region (in
, in
->mark
, in
->point
);
856 case CK_InputKillSave
:
857 copy_region (in
, in
->mark
, in
->point
);
858 delete_region (in
, in
->point
, in
->mark
);
866 case CK_InputHistoryPrev
:
869 case CK_InputHistoryNext
:
872 case CK_InputHistoryShow
:
875 case CK_InputComplete
:
879 res
= MSG_NOT_HANDLED
;
882 if (command
!= CK_InputLeftHighlight
&&
883 command
!= CK_InputRightHighlight
&&
884 command
!= CK_InputWordLeftHighlight
&&
885 command
!= CK_InputWordRightHighlight
&&
886 command
!= CK_InputBolHighlight
&& command
!= CK_InputEolHighlight
)
887 in
->highlight
= FALSE
;
892 /* --------------------------------------------------------------------------------------------- */
895 input_destroy (WInput
* in
)
899 fprintf (stderr
, "Internal error: null Input *\n");
905 if (in
->history
!= NULL
)
907 if (!in
->is_password
&& (((Widget
*) in
)->owner
->ret_value
!= B_CANCEL
))
908 history_put (in
->history_name
, in
->history
);
910 in
->history
= g_list_first (in
->history
);
911 g_list_foreach (in
->history
, (GFunc
) g_free
, NULL
);
912 g_list_free (in
->history
);
916 input_free_completions (in
);
917 g_free (in
->history_name
);
919 g_free (kill_buffer
);
923 /* --------------------------------------------------------------------------------------------- */
926 input_event (Gpm_Event
* event
, void *data
)
928 WInput
*in
= (WInput
*) data
;
930 if ((event
->type
& GPM_DOWN
) != 0)
933 input_mark_cmd (in
, FALSE
);
936 if ((event
->type
& (GPM_DOWN
| GPM_DRAG
)) != 0)
938 dlg_select_widget (in
);
940 if (event
->x
>= in
->field_width
- HISTORY_BUTTON_WIDTH
+ 1
941 && should_show_history_button (in
))
945 in
->point
= str_length (in
->buffer
);
946 if (event
->x
+ in
->term_first_shown
- 1 < str_term_width1 (in
->buffer
))
947 in
->point
= str_column_to_pos (in
->buffer
, event
->x
+ in
->term_first_shown
- 1);
949 input_update (in
, TRUE
);
951 /* A lone up mustn't do anything */
952 if (in
->highlight
&& (event
->type
& (GPM_UP
| GPM_DRAG
)) != 0)
955 if ((event
->type
& GPM_DRAG
) == 0)
956 input_mark_cmd (in
, TRUE
);
961 /* --------------------------------------------------------------------------------------------- */
962 /*** public functions ****************************************************************************/
963 /* --------------------------------------------------------------------------------------------- */
965 /** Create new instance of WInput object.
966 * @param y Y coordinate
967 * @param x X coordinate
968 * @param input_colors Array of used colors
969 * @param width Widget width
970 * @param def_text Default text filled in widget
971 * @param histname Name of history
972 * @param completion_flags Flags for specify type of completions
973 * @returns WInput object
976 input_new (int y
, int x
, const int *input_colors
, int width
, const char *def_text
,
977 const char *histname
, input_complete_t completion_flags
)
979 WInput
*in
= g_new (WInput
, 1);
980 size_t initial_buffer_len
;
982 init_widget (&in
->widget
, y
, x
, 1, width
, input_callback
, input_event
);
985 in
->history_name
= NULL
;
987 if ((histname
!= NULL
) && (*histname
!= '\0'))
989 in
->history_name
= g_strdup (histname
);
990 in
->history
= history_get (histname
);
993 if (def_text
== NULL
)
995 else if (def_text
== INPUT_LAST_TEXT
)
997 if ((in
->history
!= NULL
) && (in
->history
->data
!= NULL
))
998 def_text
= (char *) in
->history
->data
;
1003 initial_buffer_len
= strlen (def_text
);
1004 initial_buffer_len
= 1 + max ((size_t) width
, initial_buffer_len
);
1005 in
->widget
.options
|= W_IS_INPUT
;
1006 in
->completions
= NULL
;
1007 in
->completion_flags
= completion_flags
;
1008 in
->current_max_size
= initial_buffer_len
;
1009 in
->buffer
= g_new (char, initial_buffer_len
);
1011 memmove (in
->color
, input_colors
, sizeof (input_colors_t
));
1013 in
->field_width
= width
;
1015 in
->highlight
= FALSE
;
1016 in
->term_first_shown
= 0;
1017 in
->disable_update
= 0;
1019 in
->need_push
= TRUE
;
1020 in
->is_password
= FALSE
;
1022 strcpy (in
->buffer
, def_text
);
1023 in
->point
= str_length (in
->buffer
);
1029 /* --------------------------------------------------------------------------------------------- */
1032 input_callback (Widget
* w
, widget_msg_t msg
, int parm
)
1034 WInput
*in
= (WInput
*) w
;
1040 if (parm
== XCTRL ('q'))
1043 v
= input_handle_char (in
, ascii_alpha_to_cntrl (tty_getch ()));
1048 /* Keys we want others to handle */
1049 if (parm
== KEY_UP
|| parm
== KEY_DOWN
|| parm
== ESC_CHAR
1050 || parm
== KEY_F (10) || parm
== '\n')
1051 return MSG_NOT_HANDLED
;
1053 /* When pasting multiline text, insert literal Enter */
1054 if ((parm
& ~KEY_M_MASK
) == '\n')
1057 v
= input_handle_char (in
, '\n');
1062 return input_handle_char (in
, parm
);
1064 case WIDGET_COMMAND
:
1065 return input_execute_cmd (in
, parm
);
1068 case WIDGET_UNFOCUS
:
1070 input_update (in
, FALSE
);
1074 widget_move (&in
->widget
, 0, str_term_width2 (in
->buffer
, in
->point
)
1075 - in
->term_first_shown
);
1078 case WIDGET_DESTROY
:
1083 return default_proc (msg
, parm
);
1087 /* --------------------------------------------------------------------------------------------- */
1089 /** Get default colors for WInput widget.
1090 * @returns default colors
1093 input_get_default_colors (void)
1095 static input_colors_t standart_colors
;
1097 standart_colors
[WINPUTC_MAIN
] = INPUT_COLOR
;
1098 standart_colors
[WINPUTC_MARK
] = INPUT_MARK_COLOR
;
1099 standart_colors
[WINPUTC_UNCHANGED
] = INPUT_UNCHANGED_COLOR
;
1100 standart_colors
[WINPUTC_HISTORY
] = INPUT_HISTORY_COLOR
;
1102 return standart_colors
;
1105 /* --------------------------------------------------------------------------------------------- */
1108 input_set_origin (WInput
* in
, int x
, int field_width
)
1111 in
->field_width
= in
->widget
.cols
= field_width
;
1112 input_update (in
, FALSE
);
1115 /* --------------------------------------------------------------------------------------------- */
1118 input_handle_char (WInput
* in
, int key
)
1121 unsigned long command
;
1123 v
= MSG_NOT_HANDLED
;
1127 input_free_completions (in
);
1128 v
= insert_char (in
, key
);
1129 input_update (in
, TRUE
);
1134 command
= keybind_lookup_keymap_command (input_map
, key
);
1136 if (command
== CK_Ignore_Key
)
1139 return MSG_NOT_HANDLED
;
1141 port_region_marked_for_delete (in
);
1142 input_free_completions (in
);
1143 v
= insert_char (in
, key
);
1147 if (command
!= CK_InputComplete
)
1148 input_free_completions (in
);
1149 input_execute_cmd (in
, command
);
1152 input_update (in
, TRUE
); /* needed to clear in->first */
1155 input_update (in
, TRUE
);
1159 /* --------------------------------------------------------------------------------------------- */
1161 /* This function is a test for a special input key used in complete.c */
1162 /* Returns 0 if it is not a special key, 1 if it is a non-complete key
1163 and 2 if it is a complete key */
1165 input_key_is_in_map (WInput
* in
, int key
)
1167 unsigned long command
;
1171 command
= keybind_lookup_keymap_command (input_map
, key
);
1172 if (command
== CK_Ignore_Key
)
1175 return (command
== CK_InputComplete
) ? 2 : 1;
1178 /* --------------------------------------------------------------------------------------------- */
1181 input_assign_text (WInput
* in
, const char *text
)
1183 input_free_completions (in
);
1184 g_free (in
->buffer
);
1185 in
->buffer
= g_strdup (text
); /* was in->buffer->text */
1186 in
->current_max_size
= strlen (in
->buffer
) + 1;
1187 in
->point
= str_length (in
->buffer
);
1189 in
->need_push
= TRUE
;
1193 /* --------------------------------------------------------------------------------------------- */
1195 /* Inserts text in input line */
1197 input_insert (WInput
* in
, const char *text
, gboolean insert_extra_space
)
1199 input_disable_update (in
);
1200 while (*text
!= '\0')
1201 input_handle_char (in
, (unsigned char) *text
++); /* unsigned extension char->int */
1202 if (insert_extra_space
)
1203 input_handle_char (in
, ' ');
1204 input_enable_update (in
);
1205 input_update (in
, TRUE
);
1208 /* --------------------------------------------------------------------------------------------- */
1211 input_set_point (WInput
* in
, int pos
)
1215 max_pos
= str_length (in
->buffer
);
1216 pos
= min (pos
, max_pos
);
1217 if (pos
!= in
->point
)
1218 input_free_completions (in
);
1221 input_update (in
, TRUE
);
1224 /* --------------------------------------------------------------------------------------------- */
1227 input_update (WInput
* in
, gboolean clear_first
)
1229 int has_history
= 0;
1235 if (should_show_history_button (in
))
1236 has_history
= HISTORY_BUTTON_WIDTH
;
1238 if (in
->disable_update
!= 0)
1241 buf_len
= str_length (in
->buffer
);
1242 pw
= str_term_width2 (in
->buffer
, in
->point
);
1244 /* Make the point visible */
1245 if ((pw
< in
->term_first_shown
) || (pw
>= in
->term_first_shown
+ in
->field_width
- has_history
))
1247 in
->term_first_shown
= pw
- (in
->field_width
/ 3);
1248 if (in
->term_first_shown
< 0)
1249 in
->term_first_shown
= 0;
1252 /* Adjust the mark */
1253 in
->mark
= min (in
->mark
, buf_len
);
1255 if (has_history
!= 0)
1256 draw_history_button (in
);
1258 if ((((Widget
*) in
)->options
& W_DISABLED
) != 0)
1259 tty_setcolor (DISABLED_COLOR
);
1261 tty_setcolor (in
->color
[WINPUTC_UNCHANGED
]);
1263 tty_setcolor (in
->color
[WINPUTC_MAIN
]);
1265 widget_move (&in
->widget
, 0, 0);
1267 if (!in
->is_password
)
1270 tty_print_string (str_term_substring (in
->buffer
, in
->term_first_shown
,
1271 in
->field_width
- has_history
));
1276 if (input_eval_marks (in
, &m1
, &m2
))
1278 tty_setcolor (in
->color
[WINPUTC_MAIN
]);
1279 cp
= str_term_substring (in
->buffer
, in
->term_first_shown
,
1280 in
->field_width
- has_history
);
1281 tty_print_string (cp
);
1282 tty_setcolor (in
->color
[WINPUTC_MARK
]);
1283 if (m1
< in
->term_first_shown
)
1285 widget_move (&in
->widget
, 0, 0);
1286 tty_print_string (str_term_substring
1287 (in
->buffer
, in
->term_first_shown
,
1288 m2
- in
->term_first_shown
));
1294 widget_move (&in
->widget
, 0, m1
- in
->term_first_shown
);
1297 (in
->field_width
- has_history
) - (str_term_width2 (in
->buffer
, m1
) -
1298 in
->term_first_shown
));
1299 tty_print_string (str_term_substring (in
->buffer
, m1
, sel_width
));
1306 cp
= str_term_substring (in
->buffer
, in
->term_first_shown
, in
->field_width
- has_history
);
1307 for (i
= 0; i
< in
->field_width
- has_history
; i
++)
1311 tty_setcolor (in
->color
[WINPUTC_MAIN
]);
1312 tty_print_char ((cp
[0] != '\0') ? '*' : ' ');
1315 str_cnext_char (&cp
);
1323 /* --------------------------------------------------------------------------------------------- */
1326 input_enable_update (WInput
* in
)
1328 in
->disable_update
--;
1329 input_update (in
, FALSE
);
1332 /* --------------------------------------------------------------------------------------------- */
1335 input_disable_update (WInput
* in
)
1337 in
->disable_update
++;
1340 /* --------------------------------------------------------------------------------------------- */
1342 /* Cleans the input line and adds the current text to the history */
1344 input_clean (WInput
* in
)
1346 push_history (in
, in
->buffer
);
1347 in
->need_push
= TRUE
;
1348 in
->buffer
[0] = '\0';
1352 in
->highlight
= FALSE
;
1353 input_free_completions (in
);
1354 input_update (in
, FALSE
);
1357 /* --------------------------------------------------------------------------------------------- */
1360 input_free_completions (WInput
* in
)
1362 g_strfreev (in
->completions
);
1363 in
->completions
= NULL
;
1366 /* --------------------------------------------------------------------------------------------- */