OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [gdbtcl/] [console.itb] - Blame information for rev 1767

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# Console window for Insight
2
# Copyright 1998, 1999, 2001 Cygnus Solutions
3
#
4
# This program is free software; you can redistribute it and/or modify it
5
# under the terms of the GNU General Public License (GPL) as published by
6
# the Free Software Foundation; either version 2 of the License, or (at
7
# your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
 
14
 
15
body Console::constructor {args} {
16
  global gdbtk_state
17
  window_name "Console Window"
18
 
19
  debug "$args"
20
  _build_win
21
  eval itk_initialize $args
22
  add_hook gdb_no_inferior_hook [list $this idle dummy]
23
 
24
  # Right now the preferences window directly uses preference
25
  # variables.  This means that if we track the preference changes
26
  # here, things will appear weird to the user -- the console window
27
  # will change before the user chooses Accpet in the prefs window.
28
  # Until the preference window is fixed we can't enable this
29
  # dynamic tracking.  FIXME.
30
  # foreach option {gdb/console/wrap gdb/console/prompt_fg \
31
  #                 gdb/console/error_fg gdb/console/font} {
32
  #  pref add_hook $option [code $this _update_option]
33
  # }
34
 
35
  set gdbtk_state(console) $this
36
}
37
 
38
body Console::destructor {} {
39
  global gdbtk_state
40
  set gdbtk_state(console) ""
41
  remove_hook gdb_no_inferior_hook [list $this idle dummy]
42
 
43
  # foreach option {gdb/console/wrap gdb/console/prompt_fg \
44
  #                 gdb/console/error_fg gdb/console/font} {
45
  #   pref remove_hook $option [code $this _update_option]
46
  # }
47
}
48
 
49
body Console::_build_win {} {
50
  iwidgets::scrolledtext $itk_interior.stext \
51
    -vscrollmode dynamic -textbackground white
52
 
53
  set _twin [$itk_interior.stext component text]
54
 
55
  _set_wrap [pref get gdb/console/wrap]
56
 
57
  $_twin tag configure prompt_tag -foreground [pref get gdb/console/prompt_fg]
58
  $_twin tag configure err_tag -foreground [pref get gdb/console/error_fg]
59
  $_twin tag configure log_tag -foreground [pref get gdb/console/log_fg]
60
  $_twin tag configure target_tag -foreground [pref get gdb/console/target_fg]
61
  $_twin configure -font [pref get gdb/console/font]
62
 
63
  #
64
  # bind editing keys for console window
65
  #
66
  bind $_twin  "$this invoke; break"
67
 
68
  # disable this
69
  bind_plain_key $_twin Control-o "break"
70
 
71
  # History control.
72
  bind_plain_key $_twin Control-p "[code $this _previous]; break"
73
  bind $_twin  "[code $this _previous]; break"
74
  bind_plain_key $_twin Control-n "[code $this _next]; break"
75
  bind $_twin  "[code $this _next]; break"
76
  bind $_twin  "[code $this _first]; break"
77
  bind $_twin  "[code $this _first]; break"
78
  bind $_twin  "[code $this _last]; break"
79
  bind $_twin  "[code $this _last]; break"
80
 
81
  # Tab completion
82
  bind_plain_key $_twin KeyPress-Tab "[code $this _complete]; break"
83
 
84
  # Don't let left arrow or ^B go over the prompt
85
  bind_plain_key $_twin Control-b {
86
    if {[%W compare insert <= {cmdmark + 1 char}]} {
87
      break
88
    }
89
  }
90
  bind $_twin  [bind $_twin ]
91
 
92
  # Don't let Control-h, Delete, or Backspace back up over the prompt.
93
  bind_plain_key $_twin Control-h "[code $this _delete]; break"
94
 
95
  bind $_twin  "[code $this _delete]; break"
96
 
97
  bind $_twin  "[code $this _delete 1]; break"
98
 
99
  # Control-a moves to start of line.
100
  bind_plain_key $_twin Control-a {
101
    %W mark set insert {cmdmark + 1 char}
102
    %W see {insert linestart}
103
    break
104
  }
105
 
106
  # Control-u deletes to start of line.
107
  bind_plain_key $_twin Control-u {
108
    %W delete {cmdmark + 1 char} insert
109
    %W see {insert linestart}
110
  }
111
 
112
  # Control-w deletes previous word.
113
  bind_plain_key $_twin Control-w {
114
    if {[%W compare {insert -1c wordstart} > cmdmark]} {
115
      %W delete {insert -1c wordstart} insert
116
      %W see insert
117
    }
118
  }
119
 
120
  bind $_twin  "[code $this _search_history]; break"
121
  bind $_twin  "[code $this _search_history]; break"
122
  bind $_twin  "[code $this _rsearch_history]; break"
123
  bind $_twin  "[code $this _rsearch_history]; break"
124
 
125
  # Don't allow key motion to move insertion point outside the command
126
  # area.  This is done by fixing up the insertion point after any key
127
  # movement.  We only need to do this after events we do not
128
  # explicitly override.  Note that since the edit line is always the
129
  # last line, we can't possibly go past it, so we don't bother
130
  # checking that.
131
  foreach event [bind Text] {
132
    if {[string match *Key* $event] && [bind $_twin $event] == ""} {
133
      bind $_twin $event {
134
        if {[%W compare insert <= {cmdmark + 1 char}]} {
135
          %W mark set insert {cmdmark + 1 char}
136
        }
137
      }
138
    }
139
  }
140
 
141
  # Don't allow mouse to put cursor outside command line.  For some
142
  # events we do this by noticing when the cursor is outside the
143
  # range, and then saving the insertion point.  For others we notice
144
  # the saved insertion point.
145
  set pretag pre-$_twin
146
  bind $_twin <1> [format {
147
    if {[%%W compare [tkTextClosestGap %%W %%x %%y] <= cmdmark]} {
148
      %s _insertion [%%W index insert]
149
    } else {
150
      %s _insertion {}
151
    }
152
  } $this $this]
153
  bind $_twin  [format {
154
    if {[%s _insertion] != ""} {
155
      %%W mark set insert [%s _insertion]
156
    }
157
  } $this $this $this]
158
  # FIXME: has inside information.
159
  bind $_twin  [format {
160
    tkCancelRepeat
161
    if {[%s _insertion] != ""} {
162
      %%W mark set insert [%s _insertion]
163
    }
164
    %s _insertion {}
165
    break
166
  } $this $this $this]
167
 
168
  # Don't allow inserting text outside the command line.  FIXME:
169
  # requires inside information.
170
  # Also make it a little easier to paste by making the button
171
  # drags a little "fuzzy".
172
  bind $_twin  {
173
    if {!$tk_strictMotif} {
174
      if {($tkPriv(x) - 2 < %x < $tkPriv(x) + 2) \
175
            || ($tkPriv(y) - 2 < %y < $tkPriv(y) + 2)} {
176
        set tkPriv(mouseMoved) 1
177
      }
178
      if {$tkPriv(mouseMoved)} {
179
        %W scan dragto %x %y
180
      }
181
    }
182
    break
183
  }
184
  bind $_twin  [format {
185
    if {!$tkPriv(mouseMoved) || $tk_strictMotif} {
186
      %s
187
      break
188
    }
189
  } [code $this _paste 1]]
190
  bind $_twin <> "[code $this _paste 0]; break"
191
  bind $_twin <> "[code $this _paste 0]; break"
192
 
193
  _setprompt
194
  pack $itk_interior.stext -expand yes -fill both
195
 
196
  focus $_twin
197
 
198
}
199
 
200
body Console::idle {event} {
201
  set _running 0
202
}
203
 
204
# ------------------------------------------------------------------
205
#  METHOD: busy - busy event handler
206
# ------------------------------------------------------------------
207
body Console::busy {event} {
208
  set _running 1
209
}
210
 
211
# ------------------------------------------------------------------
212
#  METHOD:  insert - insert new text in the text widget
213
# ------------------------------------------------------------------
214
body Console::insert {line} {
215
  if {$_needNL} {
216
    $_twin insert {insert linestart} "\n"
217
  }
218
  # Remove all \r characters from line.
219
  set line [join [split $line \r] {}]
220
  $_twin insert {insert -1 line lineend} $line
221
 
222
  set nlines [lindex [split [$_twin index end] .] 0]
223
  if {$nlines > $throttle} {
224
    set delta [expr {$nlines - $throttle}]
225
    $_twin delete 1.0 ${delta}.0
226
  }
227
 
228
  $_twin see insert
229
  set _needNL 0
230
  ::update idletasks
231
}
232
 
233
#-------------------------------------------------------------------
234
#  METHOD:  einsert - insert error text in the text widget
235
# ------------------------------------------------------------------
236
body Console::einsert {line tag} {
237
  debug $line
238
  if {$_needNL} {
239
    $_twin insert end "\n"
240
  }
241
  $_twin insert end $line $tag
242
  $_twin see insert
243
  set _needNL 0
244
}
245
 
246
#-------------------------------------------------------------------
247
#  METHOD:  _previous - recall the previous command
248
# ------------------------------------------------------------------
249
body Console::_previous {} {
250
  if {$_histElement == -1} {
251
    # Save partial command.
252
    set _partialCommand [$_twin get {cmdmark + 1 char} {cmdmark lineend}]
253
  }
254
  incr _histElement
255
  set text [lindex $_history $_histElement]
256
  if {$text == ""} {
257
    # No dice.
258
    incr _histElement -1
259
    # FIXME flash window.
260
  } else {
261
    $_twin delete {cmdmark + 1 char} {cmdmark lineend}
262
    $_twin insert {cmdmark + 1 char} $text
263
  }
264
}
265
 
266
#-------------------------------------------------------------------
267
#  METHOD:  _search_history - search history for match
268
# ------------------------------------------------------------------
269
body Console::_search_history {} {
270
  set str [$_twin get {cmdmark + 1 char} {cmdmark lineend}]
271
 
272
  if {$_histElement == -1} {
273
    # Save partial command.
274
    set _partialCommand $str
275
    set ix [lsearch $_history ${str}*]
276
  } else {
277
    set str $_partialCommand
278
    set num [expr $_histElement + 1]
279
    set ix [lsearch [lrange $_history $num end] ${str}*]
280
    incr ix $num
281
  }
282
 
283
  set text [lindex $_history $ix]
284
  if {$text != ""} {
285
    set _histElement $ix
286
    $_twin delete {cmdmark + 1 char} {cmdmark lineend}
287
    $_twin insert {cmdmark + 1 char} $text
288
  }
289
}
290
 
291
#-------------------------------------------------------------------
292
#  METHOD:  _rsearch_history - search history in reverse for match
293
# ------------------------------------------------------------------
294
body Console::_rsearch_history {} {
295
  if {$_histElement != -1} {
296
    set str $_partialCommand
297
    set num [expr $_histElement - 1]
298
    set ix $num
299
    while {$ix >= 0} {
300
      if {[string match ${str}* [lindex $_history $ix]]} {
301
        break
302
      }
303
      incr ix -1
304
    }
305
 
306
    set text ""
307
    if {$ix >= 0} {
308
      set text [lindex $_history $ix]
309
      set _histElement $ix
310
    } else {
311
      set text $_partialCommand
312
      set _histElement -1
313
    }
314
    $_twin delete {cmdmark + 1 char} {cmdmark lineend}
315
    $_twin insert {cmdmark + 1 char} $text
316
  }
317
}
318
 
319
#-------------------------------------------------------------------
320
#  METHOD:  _next - recall the next command (scroll forward)
321
# ------------------------------------------------------------------
322
body Console::_next {} {
323
  if {$_histElement == -1} {
324
    # FIXME flash window.
325
    return
326
  }
327
  incr _histElement -1
328
  if {$_histElement == -1} {
329
    set text $_partialCommand
330
  } else {
331
    set text [lindex $_history $_histElement]
332
  }
333
  $_twin delete {cmdmark + 1 char} {cmdmark lineend}
334
  $_twin insert {cmdmark + 1 char} $text
335
}
336
 
337
#-------------------------------------------------------------------
338
#  METHOD:  _last - get the last history element
339
# ------------------------------------------------------------------
340
body Console::_last {} {
341
  set _histElement 0
342
  _next
343
}
344
 
345
#-------------------------------------------------------------------
346
#  METHOD:  _first - get the first (earliest) history element
347
# ------------------------------------------------------------------
348
body Console::_first {} {
349
  set _histElement [expr {[llength $_history] - 1}]
350
  _previous
351
}
352
 
353
 
354
 
355
#-------------------------------------------------------------------
356
#  METHOD:  _setprompt - put a prompt at the beginning of a line
357
# ------------------------------------------------------------------
358
body Console::_setprompt {{prompt {}}} {
359
  if {$_invoking} {
360
    set prompt ""
361
  } elseif {"$prompt" != ""} {
362
    # nothing
363
  } else {
364
    #set prompt [pref get gdb/console/prompt]
365
    set prompt [gdb_prompt]
366
  }
367
 
368
  $_twin insert {insert linestart} $prompt prompt_tag
369
  $_twin mark set cmdmark "insert -1 char"
370
  $_twin see insert
371
}
372
 
373
#-------------------------------------------------------------------
374
#  METHOD:  activate - run this after a command is run
375
# ------------------------------------------------------------------
376
body Console::activate {{prompt {}}} {
377
  if {$_invoking > 0} {
378
    incr _invoking -1
379
    _setprompt $prompt
380
  }
381
}
382
 
383
#-------------------------------------------------------------------
384
#  METHOD:  invoke - invoke a command
385
# ------------------------------------------------------------------
386
body Console::invoke {} {
387
  global gdbtk_state
388
 
389
  set text [$_twin get {cmdmark + 1 char} end ]
390
 
391
  if { "[string range $text 0 1]" == "tk" } {
392
    if {! [info complete $text] } {
393
      $_twin insert {insert lineend} " \\\n"
394
      $_twin see insert
395
      return
396
    }
397
  }
398
 
399
  incr _invoking
400
 
401
  set text [string trimright $text \n]
402
  if {$text == ""} {
403
    set text [lindex $_history 0]
404
    $_twin insert {insert lineend} $text
405
  }
406
  $_twin mark set insert {insert lineend}
407
  $_twin insert {insert lineend} "\n"
408
 
409
  set ok 0
410
  if {$_running} {
411
    if {[string index $text 0] == "!"} {
412
      set text [string range $text 1 end]
413
      set ok 1
414
    }
415
  }
416
 
417
  # Only push new nonempty history items.
418
  if {$text != "" && [lindex $_history 0] != $text} {
419
    lvarpush _history $text
420
  }
421
 
422
  set index [$_twin index insert]
423
 
424
  # Clear current history element, and current partial element.
425
  set _histElement -1
426
  set _partialCommand ""
427
 
428
  # Need a newline before next insert.
429
  set _needNL 1
430
 
431
  # run command
432
  if {$gdbtk_state(readline)} {
433
    set gdbtk_state(readline_response) $text
434
    return
435
  }
436
 
437
  if {!$_running || $ok} {
438
    set result [catch {gdb_immediate "$text" 1} message]
439
  } else {
440
    set result 1
441
    set message "The debugger is busy."
442
  }
443
 
444
  # gdb_immediate may take a while to finish.  Exit if
445
  # our window has gone away.
446
  if {![winfo exists $_twin]} { return }
447
 
448
  if {$result} {
449
    global errorInfo
450
    dbug W "Error: $errorInfo\n"
451
    $_twin insert end "Error: $message\n" err_tag
452
  } elseif {$message != ""} {
453
    $_twin insert $index "$message\n"
454
  }
455
 
456
  # Make the prompt visible again.
457
  activate
458
 
459
  # Make sure the insertion point is visible.
460
  $_twin see insert
461
}
462
 
463
#-------------------------------------------------------------------
464
#  PRIVATE METHOD:  _delete - Handle a Delete of some sort.
465
# ------------------------------------------------------------------
466
body Console::_delete {{right 0}} {
467
 
468
  # If we are deleting to the right, and we have this turned off,
469
  # delete to the right.
470
 
471
  if {$right && ![pref get gdb/console/deleteLeft]} {
472
    set right 0
473
  }
474
 
475
  if {!$right} {
476
    set insert_valid [$_twin compare insert > {cmdmark + 1 char}]
477
    set delete_loc "insert-1c"
478
  } else {
479
    set insert_valid [$_twin compare insert > cmdmark]
480
    set delete_loc "insert"
481
  }
482
 
483
  # If there is a selection on the command line, delete it,
484
  # If there is a selection above the command line, do a
485
  # regular delete, but don't delete the prompt.
486
  # If there is no selection, do the delete.
487
 
488
  if {![catch {$_twin index sel.first}]} {
489
    if {[$_twin compare sel.first <= cmdmark]} {
490
      if {$insert_valid} {
491
        $_twin delete $delete_loc
492
      }
493
    } else {
494
      $_twin delete sel.first sel.last
495
    }
496
  } elseif {$insert_valid} {
497
    $_twin delete $delete_loc
498
  }
499
}
500
 
501
#-------------------------------------------------------------------
502
#  PRIVATE METHOD:  _insertion - Set or get saved insertion point
503
# ------------------------------------------------------------------
504
body Console::_insertion {args} {
505
  if {! [llength $args]} {
506
    return $_saved_insertion
507
  } else {
508
    set _saved_insertion [lindex $args 0]
509
  }
510
}
511
 
512
# ------------------------------------------------------------------
513
#  METHOD:  _paste - paste the selection into the console window
514
# ------------------------------------------------------------------
515
body Console::_paste {{check_primary 1}} {
516
  set sel {}
517
 
518
  if {!$check_primary || [catch {selection get} sel] || $sel == ""} {
519
    if {[catch {selection get -selection CLIPBOARD} sel] || $sel == ""} {
520
      return
521
    }
522
  }
523
 
524
  #if there is a selection, insert over it:
525
  if {![catch {$_twin index sel.first}]
526
      && [$_twin compare sel.first > {cmdmark + 1 char}]} {
527
    set point [$_twin index sel.first]
528
    $_twin delete sel.first sel.last
529
    $_twin insert $point $sel
530
  } else {
531
    $_twin insert insert $sel
532
  }
533
}
534
 
535
# public method for testing only
536
body Console::get_text {} {
537
  return $_twin
538
}
539
 
540
# ------------------------------------------------------------------
541
#  METHOD:  _find_lcp - Return the longest common prefix in SLIST.
542
#              Can be empty string.
543
# ------------------------------------------------------------------
544
body Console::_find_lcp {slist} {
545
  # Handle trivial cases where list is empty or length 1
546
  if {[llength $slist] <= 1} {return [lindex $slist 0]}
547
 
548
  set prefix [lindex $slist 0]
549
  set prefixlast [expr [string length $prefix] - 1]
550
 
551
  foreach str [lrange $slist 1 end] {
552
    set test_str [string range $str 0 $prefixlast]
553
    while {[string compare $test_str $prefix] != 0} {
554
      incr prefixlast -1
555
      set prefix [string range $prefix 0 $prefixlast]
556
      set test_str [string range $str 0 $prefixlast]
557
    }
558
    if {$prefixlast < 0} break
559
  }
560
  return $prefix
561
}
562
 
563
# ------------------------------------------------------------------
564
#  METHOD:  _find_completion - Look through COMPLETIONS to generate
565
#             the suffix needed to do command
566
# ------------------------------------------------------------------
567
body Console::_find_completion {cmd completions} {
568
  # Get longest common prefix
569
  set lcp [_find_lcp $completions]
570
  set cmd_len [string length $cmd]
571
  # Return suffix beyond end of cmd
572
  return [string range $lcp $cmd_len end]
573
}
574
 
575
# ------------------------------------------------------------------
576
#  METHOD: _complete - Command line completion
577
# ------------------------------------------------------------------
578
body Console::_complete {} {
579
 
580
  set command_line [$_twin get {cmdmark + 1 char} {cmdmark lineend}]
581
  set choices [gdb_cmd "complete $command_line" 1]
582
  set choices [string trimright $choices \n]
583
  set choices [split $choices \n]
584
 
585
  # Just do completion if this is the first tab
586
  if {!$_saw_tab} {
587
    set _saw_tab 1
588
    set completion [_find_completion $command_line $choices]
589
 
590
    # Here is where the completion is actually done.  If there
591
    # is one match, complete the command and print a space.
592
    # If two or more matches, complete the command and beep.
593
    # If no match, just beep.
594
    switch [llength $choices] {
595
 
596
      1 {
597
        $_twin insert end "$completion "
598
        set _saw_tab 0
599
        return
600
      }
601
 
602
      default {
603
        $_twin insert end $completion
604
      }
605
    }
606
    bell
607
    $_twin see end
608
    bind $_twin  [code $this _reset_tab]
609
  } else {
610
    # User hit another consecutive tab.  List the choices.
611
    # Note that at this point, choices may contain commands
612
    # with spaces.  We have to lop off everything before (and
613
    # including) the last space so that the completion list
614
    # only shows the possibilities for the last token.
615
    set choices [lsort $choices]
616
    if {[regexp ".* " $command_line prefix]} {
617
      regsub -all $prefix $choices {} choices
618
    }
619
    if {[llength choices] != 0} {
620
      insert "\nCompletions:\n[join $choices \ ]\n"
621
      $_twin see end
622
      bind $_twin  [code $this _reset_tab]
623
    }
624
  }
625
}
626
 
627
# ------------------------------------------------------------------
628
#  METHOD:  _reset_tab - Helper method for tab completion. Used
629
#             to reset the tab when a key is pressed.
630
# ------------------------------------------------------------------
631
body Console::_reset_tab {} {
632
  bind $_twin  {}
633
  set _saw_tab 0
634
}
635
 
636
 
637
# ------------------------------------------------------------------
638
#  METHOD:  _set_wrap - Set wrap mode
639
# ------------------------------------------------------------------
640
body Console::_set_wrap {wrap} {
641
  if { $wrap } {
642
    set hsm none
643
    set wv char
644
  } else {
645
    set hsm dynamic
646
    set wv none
647
  }
648
 
649
  $itk_interior.stext configure -hscrollmode $hsm
650
  $_twin configure -wrap $wv
651
}
652
 
653
# ------------------------------------------------------------------
654
#  METHOD:  _update_option - Update in response to preference change
655
# ------------------------------------------------------------------
656
body Console::_update_option {name value} {
657
  switch -- $name {
658
    gdb/console/wrap {
659
      _set_wrap $value
660
    }
661
 
662
    gdb/console/prompt_fg {
663
      $_twin tag configure prompt_tag -foreground $value
664
    }
665
 
666
    gdb/console/error_fg {
667
      $_twin tag configure err_tag -foreground $value
668
    }
669
 
670
    gdb/console/font {
671
      $_twin configure -font $value
672
    }
673
  }
674
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.