diakonos 0.8.5 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,6 +1,21 @@
1
1
  Diakonos Changelog
2
2
  ------------------
3
3
 
4
+ 0.8.6
5
+
6
+ - Find-as-you-type added.
7
+ - Help system added.
8
+ - print_mapped_function added.
9
+ - User-definable status line variables added.
10
+ - :after_open and :after_buffer_switch hooks added.
11
+ - Sample script for git branch status variable added.
12
+ - comment_out and uncomment functions added.
13
+ - comment_string and comment_close_string settings added.
14
+ - Added -m (--open-matching) command line argument.
15
+ - wrap_paragraph function and wrap_margin setting added for hard wrapping text.
16
+ - columnize function and column_delimiter setting added.
17
+ - Numerous small fixes, adjustments and refactorings.
18
+
4
19
  0.8.5
5
20
 
6
21
  - Added 256 colour support.
data/README CHANGED
@@ -61,9 +61,8 @@ or, for other options and arguments,
61
61
 
62
62
  diakonos --help
63
63
 
64
- For a quick introduction, see
65
-
66
- http://wiki.purepistos.net/doku.php?id=Diakonos:Getting-Started
64
+ For help using Diakonos, simply press F1 from within the editor to use the
65
+ interactive help system.
67
66
 
68
67
  ----------------------------------------------------------------
69
68
 
@@ -12,6 +12,14 @@ colour 41 15 233 # XML nodes; white on light black
12
12
  colour 42 45 233 # XML attributes; light blue on black
13
13
  colour 43 123 233 # XML namespaces; light blue on black
14
14
 
15
+ # Diakonos help files
16
+
17
+ lang.dhf.format.default white
18
+ lang.dhf.format.selection inverse
19
+ lang.dhf.format.found yellow inverse
20
+ lang.dhf.tokens.tags.format blue
21
+ lang.dhf.tokens.title.format 33
22
+
15
23
  # Ruby
16
24
 
17
25
  lang.ruby.format.default white bold
@@ -1,3 +1,5 @@
1
+ #suppress_welcome true
2
+
1
3
  logfile ~/.diakonos/diakonos.log
2
4
 
3
5
  # When the cursor is view.margin.y lines or less from the top or
@@ -66,7 +68,7 @@ use_magic_file false
66
68
 
67
69
  # Use "% syntax" as placeholders
68
70
  # e.g. %d for decimal integers, %s for strings
69
- status.left -- %s %s%s%s -- (%s) -
71
+ status.left -- %s %s%s%s -- (%s) --%s
70
72
  status.right - Buf %d of %d --- L%3d/%3d C%2d --
71
73
  # The string to use to fill in the space between the left and right sides
72
74
  # of the status line.
@@ -77,7 +79,7 @@ status.unnamed_str (unnamed file)
77
79
  status.read_only_str (read-only)
78
80
  # status.vars: any subset of:
79
81
  # line row num_lines col filename modified type buffer_number num_buffers selecting read_only
80
- status.vars filename modified read_only selecting type buffer_number num_buffers row num_lines col
82
+ status.vars filename modified read_only selecting type @git_branch buffer_number num_buffers row num_lines col
81
83
  status.format inverse
82
84
 
83
85
  # ---------------------------------------------------------------------
@@ -145,7 +147,7 @@ key esc [ 4 ~;cursorEOL
145
147
  key esc [ 8 ~;cursorEOL
146
148
  key pageup;pageUp
147
149
  key pagedown;pageDown
148
- key ctrl+a;cursorBOL
150
+ #key ctrl+a;cursorBOL
149
151
  key ctrl+e;cursorEOL
150
152
  key alt+<;cursorBOF
151
153
  key esc [ 1 ; 5 H cursorBOF
@@ -207,6 +209,8 @@ key ctrl+k;deleteAndStoreLine
207
209
  key ctrl+alt+k;deleteToEOL
208
210
  key esc del;collapseWhitespace
209
211
  key esc [ 3 ; 3 ~ collapseWhitespace
212
+ key alt+w wrap_paragraph
213
+ key alt+a columnize
210
214
  key enter;carriageReturn
211
215
  key tab;parsedIndent
212
216
  #key tab;indent
@@ -264,6 +268,7 @@ key ctrl+space;anchorSelection
264
268
  key ctrl+c;copySelection
265
269
  key ctrl+x;cutSelection
266
270
  key alt+u;removeSelection
271
+ key ctrl+a select_all
267
272
 
268
273
  # If you are using KDE, you can uncomment these lines to synchronize
269
274
  # the Diakonos clipboard with the KDE clipboard
@@ -278,6 +283,8 @@ key ctrl+b select_block
278
283
  key ctrl+alt+d f select_block /^Index: /, /^(Index: |$)/, false
279
284
  # Select a diff hunk in a patch
280
285
  key ctrl+alt+d h select_block /^@@ /, /^(@@ |$)/, false
286
+ key esc # comment_out
287
+ key esc @ uncomment
281
288
 
282
289
  key ctrl+alt+v;showClips
283
290
  key ctrl+v;paste
@@ -300,7 +307,8 @@ key esc [ 1 3 ~;findAgain "down"
300
307
  key f15;findAgain "up"
301
308
  key esc [ 2 8 ~ findAgain "up"
302
309
  key esc O 2 R;findAgain "up"
303
- key ctrl+r;searchAndReplace
310
+ key ctrl+r searchAndReplace
311
+ key alt+r searchAndReplace CASE_SENSITIVE
304
312
  key ctrl+alt+u;clearMatches
305
313
  key alt+c;close_code
306
314
 
@@ -310,13 +318,14 @@ key esc [ 1 2 ~ shell
310
318
  key esc [ [ B shell
311
319
  key f8;execute
312
320
  key esc F;execute "glark '$i' $F | less"
313
- key esc d shell "diff -U 5 -w -b $c $s"
321
+ key esc d shell "diff -U 5 -w -b $c $s", "clipboard.diff"
314
322
  #key esc F;shell "grep -n '$i' $F"
315
323
  #key esc F;execute "grep -n '$i' $F | less"
316
- key f14 evaluate
317
- key esc O 2 Q evaluate
318
- esc [ 2 6 ~ evaluate
319
- key ctrl+alt+c;shell "ruby -c $f"
324
+ #key esc l execute "aspell check $f"
325
+ key f14 evaluate
326
+ key esc O 2 Q evaluate
327
+ key esc [ 2 6 ~ evaluate
328
+ key ctrl+alt+c shell "ruby -c $f"
320
329
 
321
330
  # To use the following:
322
331
  # 1) Copy to the clipboard some Ruby code which operates on stdin text and outputs to stdout.
@@ -330,6 +339,7 @@ key ctrl+alt+p;pasteShellResult "cat $s | ruby $c"
330
339
  #key ctrl+alt+p;pasteShellResult "cat $s | awk -f $c"
331
340
 
332
341
  key alt+k printKeychain
342
+ key esc K print_mapped_function
333
343
  key alt+m;toggleMacroRecording
334
344
  key f4 playMacro
335
345
  key esc O S playMacro
@@ -407,6 +417,28 @@ lang.text.indent.auto true
407
417
  lang.text.indent.roundup false
408
418
  #lang.text.indent.using_tabs true
409
419
  lang.text.tabsize 8
420
+ lang.text.wrap_margin 80
421
+
422
+ # Diakonos help files
423
+
424
+ lang.dhf.filemask \.dhf
425
+ lang.dhf.format.default white
426
+ lang.dhf.format.selection inverse
427
+ lang.dhf.format.found yellow inverse
428
+ lang.dhf.tokens.tags (^Tags: .+)
429
+ lang.dhf.tokens.tags.format blue
430
+ lang.dhf.tokens.title (^# .*)
431
+ lang.dhf.tokens.title.format 8 bold
432
+ lang.dhf.tokens.subtitle (^## .*)
433
+ lang.dhf.tokens.subtitle.format cyan bold
434
+ lang.dhf.tokens.subsubtitle (^### .*)
435
+ lang.dhf.tokens.subsubtitle.format cyan
436
+ lang.dhf.tokens.keys <(.+?)>
437
+ lang.dhf.tokens.keys.format white bold
438
+ lang.dhf.indent.size 2
439
+ lang.dhf.indent.auto true
440
+ lang.dhf.indent.roundup true
441
+ lang.dhf.wrap_margin 80
410
442
 
411
443
  # XML
412
444
 
@@ -429,6 +461,8 @@ lang.xml.tokens.comments.open (<!--)
429
461
  lang.xml.tokens.comments.close (-->)
430
462
  lang.xml.tokens.comments.format 8
431
463
  lang.xml.tokens.comments.change_to xml_comment
464
+ lang.xml.comment_string <!--
465
+ lang.xml.comment_close_string " -->"
432
466
  lang.xml.tokens.template.open \[@--
433
467
  lang.xml.tokens.template.close --@\]
434
468
  lang.xml.tokens.template.format brown
@@ -495,6 +529,8 @@ lang.html.tokens.comments.open (<!--)
495
529
  lang.html.tokens.comments.close (-->)
496
530
  lang.html.tokens.comments.format 8
497
531
  lang.html.tokens.comments.change_to html_comment
532
+ lang.html.comment_string <!--
533
+ lang.html.comment_close_string " -->"
498
534
  lang.html.closers.tag.regexp <([^/> ]*)
499
535
  lang.html.closers.tag.closer { |m| "</" + m[ 1 ] + ">" }
500
536
  lang.html_tag.format.default white bold
@@ -547,6 +583,8 @@ lang.css.tokens.colours.format yellow bold
547
583
  lang.css.tokens.long_comments.open \/\*
548
584
  lang.css.tokens.long_comments.close \*\/
549
585
  lang.css.tokens.long_comments.format 8 bold
586
+ lang.css.comment_string /*
587
+ lang.css.comment_close_string " */"
550
588
  lang.css.tokens.numbers \b([0-9]+\.[0-9]+|[0-9]+)
551
589
  lang.css.tokens.numbers.format blue bold
552
590
  lang.css.tokens.units [^A-Za-z](em|pt|px)\b
@@ -555,6 +593,7 @@ lang.css.tokens.html_elements.case_insensitive \b(A|ABBR|ACRONYM|ADDRES|APPLET|A
555
593
  lang.css.tokens.html_elements.format green
556
594
  lang.css.tokens.values \b(auto|block|inherit|inline|larger|none|smaller|solid)\b
557
595
  lang.css.tokens.values.format blue bold
596
+ lang.css.column_delimiters :|,
558
597
 
559
598
  # Ruby
560
599
 
@@ -575,6 +614,7 @@ lang.ruby.tokens.instance_variables (@[A-Za-z_][A-Za-z_0-9]*)
575
614
  lang.ruby.tokens.instance_variables.format white bold
576
615
  lang.ruby.tokens.comments (#.*)
577
616
  lang.ruby.tokens.comments.format 8 bold
617
+ lang.ruby.comment_string #
578
618
  lang.ruby.tokens.regular_expressions (\/.+?[^\\]\/)
579
619
  lang.ruby.tokens.regular_expressions.format red bold
580
620
  lang.ruby.tokens.regular_expressions2 (%r\{.+?[^\}]\})
@@ -617,11 +657,12 @@ lang.ruby.indent.auto true
617
657
  lang.ruby.indent.roundup true
618
658
  #lang.ruby.indent.using_tabs true
619
659
  lang.ruby.tabsize 2
620
- lang.ruby.indent.indenters ^\s*(case|def|begin|ensure|when|else|ensure|for|while|elsif|if|class|module|rescue)\b|([{\[(]$|\{\s*\|[\w\s,]*\|\s*$)|\b(do)\b
660
+ lang.ruby.indent.indenters ^\s*(case|def|begin|ensure|when|else|ensure|for|while|until|elsif|if|class|module|rescue)\b|([{\[(]$|\{\s*\|[\w\s,]*\|\s*$)|\b(do)\b
621
661
  lang.ruby.indent.unindenters ^\s*(end|else|elsif|ensure|when|rescue)\b|(^\s+[\]})])
622
662
  lang.ruby.indent.preventers (\".+?[^\\]\")|('.+?[^\\]')|(`.+?[^\\]`)|(\/.+?[^\\]\/)|(^\s*#.*)|\S\s+if
623
663
  lang.ruby.indent.ignore ^\s*$
624
664
  lang.ruby.context.ignore ^=(begin|end)$
665
+ lang.ruby.column_delimiters =>?|:|,
625
666
 
626
667
  # PHP
627
668
 
@@ -640,6 +681,7 @@ lang.php.tokens.constants \b([A-Z_]+|[A-Z_][A-Z0-9_]+)\b
640
681
  lang.php.tokens.constants.format yellow bold
641
682
  lang.php.tokens.comments (\/\/.*)
642
683
  lang.php.tokens.comments.format 8 bold
684
+ lang.php.comment_string //
643
685
  lang.php.tokens.preprocessor (^\s*#.*)
644
686
  lang.php.tokens.preprocessor.format yellow bold
645
687
  lang.php.tokens.non_alphanum ([!@#$%\^&*()\[\]{}/?=+\-\\|,<.>;:])
@@ -674,6 +716,7 @@ lang.perl.format.selection inverse
674
716
  lang.perl.format.found yellow inverse
675
717
  lang.perl.tokens.comments (#.*)
676
718
  lang.perl.tokens.comments.format 8 bold
719
+ lang.perl.comment_string #
677
720
  lang.perl.tokens.constants \b([A-Z_]+|[A-Z_][A-Z0-9_]+)\b
678
721
  lang.perl.tokens.constants.format yellow bold
679
722
  lang.perl.tokens.non_alphanum [!#^&*()\[\]{}/?=+\-\\|,<.>;:~]
@@ -705,6 +748,7 @@ lang.perl.indent.unindenters (case|^\s+[\]})])
705
748
  lang.perl.indent.preventers (\".+?[^\\]\")|('.+?[^\\]')|(`.+?[^\\]`)|(\/.+?[^\\]\/)|(^\s*#.*)
706
749
  lang.perl.indent.ignore ^\s*$
707
750
  lang.perl.context.ignore ^(.+:|\s*\{?)$
751
+ lang.perl.column_delimiters =>?|:|,
708
752
 
709
753
  # Python
710
754
 
@@ -719,6 +763,7 @@ lang.python.tokens.non_alphanum [@!#$%^&*()\[\]{}/?=+\-\\|,<.>;:~]
719
763
  lang.python.tokens.non_alphanum.format white
720
764
  lang.python.tokens.comments (#.*)
721
765
  lang.python.tokens.comments.format 8 bold
766
+ lang.python.comment_string #
722
767
  lang.python.tokens.doublequoted_strings (\".*?[^\\]\")
723
768
  lang.python.tokens.doublequoted_strings.format green bold
724
769
  lang.python.tokens.singlequoted_strings ('.*?[^\\]')
@@ -753,6 +798,7 @@ lang.java.tokens.constants \b([A-Z_]+|[A-Z_][A-Z0-9_]+)\b
753
798
  lang.java.tokens.constants.format yellow bold
754
799
  lang.java.tokens.comments (\/\/.*)
755
800
  lang.java.tokens.comments.format 8 bold
801
+ lang.java.comment_string //
756
802
  lang.java.tokens.non_alphanum ([!@#$%\^&*()\[\]{}/?=+\-\\|,<.>;:])
757
803
  lang.java.tokens.non_alphanum.format white
758
804
  lang.java.tokens.long_comments.open \/\*
@@ -771,6 +817,7 @@ lang.java.indent.ignore ^(.+:|\s*?)$
771
817
  lang.java.context.ignore ^(.+:|\s*\{?)$
772
818
  lang.java.closers.for.regexp for$
773
819
  lang.java.closers.for.closer { |m| "( $i = 0; $i < limit; $i++ ) {\n%_\n}" }
820
+ lang.java.column_delimiters =|:|,
774
821
 
775
822
  # C
776
823
 
@@ -788,6 +835,7 @@ lang.c.tokens.constants \b([A-Z_]+|[A-Z_][A-Z0-9_]+)\b
788
835
  lang.c.tokens.constants.format yellow bold
789
836
  lang.c.tokens.comments (\/\/.*)
790
837
  lang.c.tokens.comments.format 8 bold
838
+ lang.c.comment_string //
791
839
  lang.c.tokens.preprocessor (^\s*#.*)
792
840
  lang.c.tokens.preprocessor.format yellow bold
793
841
  lang.c.tokens.non_alphanum ([!@#$%\^&*()\[\]{}/?=+\-\\|,<.>;:])
@@ -815,6 +863,7 @@ lang.conf.tokens.commands ^\s*([^\s=]+)
815
863
  lang.conf.tokens.commands.format cyan bold
816
864
  lang.conf.tokens.comments (^\s*#.*)
817
865
  lang.conf.tokens.comments.format yellow bold
866
+ lang.conf.comment_string #
818
867
  lang.conf.tokens.doublequoted_strings (\".*?[^\\]\")
819
868
  lang.conf.tokens.doublequoted_strings.format green bold
820
869
  lang.conf.tokens.singlequoted_strings ('.*?[^\\]')
@@ -832,6 +881,7 @@ lang.crontab.format.selection inverse
832
881
  lang.crontab.format.found yellow inverse
833
882
  lang.crontab.tokens.comments (^\s*#.*)
834
883
  lang.crontab.tokens.comments.format yellow bold
884
+ lang.crontab.comment_string #
835
885
  lang.crontab.tokens.schedule ^((?:[0-9\/*,-]+\s+){5})
836
886
  lang.crontab.tokens.schedule.format cyan bold
837
887
  lang.crontab.tokens.commands ^(\S+=.+)
@@ -847,6 +897,7 @@ lang.fstab.format.selection inverse
847
897
  lang.fstab.format.found yellow inverse
848
898
  lang.fstab.tokens.comments (^\s*#.*)
849
899
  lang.fstab.tokens.comments.format yellow bold
900
+ lang.fstab.comment_string #
850
901
  lang.fstab.indent.size 4
851
902
  lang.fstab.indent.auto true
852
903
  lang.fstab.indent.roundup true
@@ -862,7 +913,8 @@ lang.sql.indent.size 4
862
913
  lang.sql.indent.auto true
863
914
  lang.sql.indent.roundup true
864
915
  #lang.sql.indent.using_tabs true
865
- lang.sql.tokens.reserved_words.case_insensitive \b(ABSOLUTE|ACCESS|ACTION|ADD|ADMIN|AFTER|ALIAS|ALL|ALLOCATE|AND|ANY|ARE|AS|ASC|ASSERTION|AT|AUDIT|AUTHORIZATION|AVG|BEFORE|BEGIN|BETWEEN|BIT_LENGTH|BOTH|BREADTH|BY|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR_LENGTH|CHARACTER_LENGTH|CHECK|CLASS|CLOSE|CLUSTER|COALESCE|COBOL|COLLATE|COLLATION|COLUMN|COMPLETION|COMPRESS|COMPUTED|CONCAT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONSTRUCTOR|CONTINUE|CONVERT|CORRESPONDING|COUNT|CROSS|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURRENT|CURSOR|CYCLE|DATA|DAY|DBHIGH|DBKEY|DBLOW|DBMAC|DEALLOCATE|DECLARE|DECODE|DEFAULT|DEFERRABLE|DEFERRED|DEPTH|DEREF|DESC|DESCRIBE|DESCRIPTOR|DESTROY|DESTRUCTOR|DIAGNOSTICS|DICTIONARY|DISCONNECT|DISTINCT|DO|DOMAIN|EACH|ELEMENT|ELSE|ELSEIF|END-EXEC|END|EQUALS|ESCAPE|EXCEPT|EXCEPTION|EXCEPTIONS|EXCLUSIVE|EXISTS|EXTERNAL|EXTERNALLY|EXTRACT|FALSE|FILE|FIRST|FOR|FOREIGN|FORTRAN|FOUND|FROM|FULL|FUNCTION|GENERAL|GET|GLOBAL|GO|GOTO|GROUP|HAVING|HOUR|IDENTIFIED|IDENTITY|IF|IGNORE|IMMEDIATE|IN|INCREMENT|INDEX|INDICATOR|INITIAL|INITIALLY|INNER|INOUT|INPUT|INSENSITIVE|INSTEAD|INTERSECT|INTERVAL|INTO|IS|ISOLATION|JOIN|KEY|LABEL|LANGUAGE|LAST|LEADING|LEAVE|LEFT|LESS|LEVEL|LIKE|LIMIT|LOCAL|LOCK|LOOP|LOWER|MATCH|MAX|MAXEXTENTS|MIN|MINUS|MINUTE|MLSLABEL|MLS_LABEL_FORMAT|MODE|MODIFY|MODULE|MONTH|MOVE|MULTISET|NAMES|NATIONAL|NATURAL|NEW_TABLE|NEXT|NO|NOAUDIT|NOCOMPRESS|NONE|NOT|NOWAIT|NULL|NULLIF|NUMBER|NVL|OCTET_LENGTH|OF|OFF|OFFLINE|OID|OLD|OLD_TABLE|ON|ONLINE|ONLY|OPEN|OPERATION|OPERATORS|OPTION|OR|ORDER|OTHERS|OUT|OUTER|OUTPUT|OVERLAPS|PAD|PARAMETER|PARTIAL|PASCAL|PCTFREE|PENDANT|PLI|POSITION|PRECISION|PREORDER|PRESERVE|PRIMARY|PRIOR|PRIVATE|PRIVILEGES|PROCEDURE|PROTECTED|PUBLIC|RAW|READ|READUP|REAL|RECORD|RECURSIVE|REF|REFERENCES|REFERENCING|RELATIVE|RENAME|REPLACE|REPRESENTATION|RESIGNAL|RESOURCE|RESTRICT|RETURN|RETURNS|RIGHT|ROLE|ROUTINE|ROW|ROWID|ROWNUM|ROWS|SAVEPOINT|SCHEMA|SCROLL|SEARCH|SECOND|SECTION|SENSITIVE|SEQUENCE|SESSION|SESSION_USER|SET|SHARE|SIGNAL|SIMILAR|SIZE|SOME|SPACE|SPECIFIC|SQL|SQLCODE|SQLERROR|SQLEXCEPTION|SQLSTATE|SQLWARNING|START|STRUCTURE|SUBSTRING|SUCCESSFUL|SUM|SYNONYM|SYSDATE|SYSTEM_USER|TABLE|TEMPLATE|TEMPORARY|TEST|THAN|THEN|THERE|SQ92|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIGGER|TRIM|TRUE|TUPLE|TYPE|UID|UNDER|UNION|UNIQUE|UNKNOWN|UPPER|USAGE|USER|USING|VALIDATE|VALUE|VALUES|VARIABLE|VARIANT|VIRTUAL|VARYING|VIEW|VISIBLE|VOID|WAIT|WHEN|WHENEVER|WHERE|WHILE|WITH|WITHOUT|WORK|WRITE|WRITEDOWN|WRITEUP|YEAR|ZONE)\b
916
+ #lang.sql.tokens.reserved_words.case_insensitive \b(ABSOLUTE|ACCESS|ACTION|ADD|ADMIN|AFTER|ALIAS|ALL|ALLOCATE|AND|ANY|ARE|AS|ASC|ASSERTION|AT|AUDIT|AUTHORIZATION|AVG|BEFORE|BEGIN|BETWEEN|BIT_LENGTH|BOTH|BREADTH|BY|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR_LENGTH|CHARACTER_LENGTH|CHECK|CLASS|CLOSE|CLUSTER|COALESCE|COBOL|COLLATE|COLLATION|COLUMN|COMPLETION|COMPRESS|COMPUTED|CONCAT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONSTRUCTOR|CONTINUE|CONVERT|CORRESPONDING|COUNT|CROSS|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURRENT|CURSOR|CYCLE|DATA|DAY|DBHIGH|DBKEY|DBLOW|DBMAC|DEALLOCATE|DECLARE|DECODE|DEFAULT|DEFERRABLE|DEFERRED|DEPTH|DEREF|DESC|DESCRIBE|DESCRIPTOR|DESTROY|DESTRUCTOR|DIAGNOSTICS|DICTIONARY|DISCONNECT|DISTINCT|DO|DOMAIN|EACH|ELEMENT|ELSE|ELSEIF|END-EXEC|END|EQUALS|ESCAPE|EXCEPT|EXCEPTION|EXCEPTIONS|EXCLUSIVE|EXISTS|EXTERNAL|EXTERNALLY|EXTRACT|FALSE|FILE|FIRST|FOR|FOREIGN|FORTRAN|FOUND|FROM|FULL|FUNCTION|GENERAL|GET|GLOBAL|GO|GOTO|GROUP|HAVING|HOUR|IDENTIFIED|IDENTITY|IF|IGNORE|IMMEDIATE|IN|INCREMENT|INDEX|INDICATOR|INITIAL|INITIALLY|INNER|INOUT|INPUT|INSENSITIVE|INSTEAD|INTERSECT|INTERVAL|INTO|IS|ISOLATION|JOIN|KEY|LABEL|LANGUAGE|LAST|LEADING|LEAVE|LEFT|LESS|LEVEL|LIKE|LIMIT|LOCAL|LOCK|LOOP|LOWER|MATCH|MAX|MAXEXTENTS|MIN|MINUS|MINUTE|MLSLABEL|MLS_LABEL_FORMAT|MODE|MODIFY|MODULE|MONTH|MOVE|MULTISET|NAMES|NATIONAL|NATURAL|NEW_TABLE|NEXT|NO|NOAUDIT|NOCOMPRESS|NONE|NOT|NOWAIT|NULL|NULLIF|NUMBER|NVL|OCTET_LENGTH|OF|OFF|OFFLINE|OID|OLD|OLD_TABLE|ON|ONLINE|ONLY|OPEN|OPERATION|OPERATORS|OPTION|OR|ORDER|OTHERS|OUT|OUTER|OUTPUT|OVERLAPS|PAD|PARAMETER|PARTIAL|PASCAL|PCTFREE|PENDANT|PLI|POSITION|PRECISION|PREORDER|PRESERVE|PRIMARY|PRIOR|PRIVATE|PRIVILEGES|PROCEDURE|PROTECTED|PUBLIC|RAW|READ|READUP|REAL|RECORD|RECURSIVE|REF|REFERENCES|REFERENCING|RELATIVE|RENAME|REPLACE|REPRESENTATION|RESIGNAL|RESOURCE|RESTRICT|RETURN|RETURNS|RIGHT|ROLE|ROUTINE|ROW|ROWID|ROWNUM|ROWS|SAVEPOINT|SCHEMA|SCROLL|SEARCH|SECOND|SECTION|SENSITIVE|SEQUENCE|SESSION|SESSION_USER|SET|SHARE|SIGNAL|SIMILAR|SIZE|SOME|SPACE|SPECIFIC|SQL|SQLCODE|SQLERROR|SQLEXCEPTION|SQLSTATE|SQLWARNING|START|STRUCTURE|SUBSTRING|SUCCESSFUL|SUM|SYNONYM|SYSDATE|SYSTEM_USER|TABLE|TEMPLATE|TEMPORARY|TEST|THAN|THEN|THERE|SQ92|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIGGER|TRIM|TRUE|TUPLE|TYPE|UID|UNDER|UNION|UNIQUE|UNKNOWN|UPPER|USAGE|USER|USING|VALIDATE|VALUE|VALUES|VARIABLE|VARIANT|VIRTUAL|VARYING|VIEW|VISIBLE|VOID|WAIT|WHEN|WHENEVER|WHERE|WHILE|WITH|WITHOUT|WORK|WRITE|WRITEDOWN|WRITEUP|YEAR|ZONE)\b
917
+ lang.sql.tokens.reserved_words.case_insensitive \b(ALL|AND|ANY|AS|ASC|BEGIN|BY|CASCADE|CASE|CAST|CHECK|COALESCE|COLUMN|CONSTRAINT|COUNT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURSOR|DECLARE|DEFAULT|DESC|DISTINCT|DO|ELSE|ELSEIF|END|EXCEPT|EXISTS|FALSE|FIRST|FOR|FOREIGN|FOUND|FROM|FULL|FUNCTION|GROUP|HAVING|HOUR|IF|IN|INCREMENT|INDEX|INNER|INPUT|INSTEAD|INTERSECT|INTERVAL|INTO|IS|JOIN|KEY|LANGUAGE|LAST|LEFT|LIKE|LIMIT|LOOP|MAX|MIN|NATURAL|NEXT|NO|NONE|NOT|NULL|NUMBER|OF|OFF|OLD|ON|ONLY|OR|ORDER|OUT|OUTER|PARTIAL|PRECISION|PRIMARY|REAL|RECORD|REF|REFERENCES|REPLACE|RESTRICT|RETURN|RETURNS|RIGHT|SCHEMA|SEQUENCE|SET|SUM|TABLE|TEMPORARY|THAN|THEN|TO|TRANSACTION|TRIGGER|TRUE|TYPE|UNION|UNIQUE|UPPER|USING|VALUE|VALUES|VARYING|VIEW|WHEN|WHERE|WHILE|WITH|WITHOUT|WORK)\b
866
918
  lang.sql.tokens.reserved_words.format white
867
919
  lang.sql.tokens.commands.case_insensitive \b(ALTER|COMMENT|COMMIT|CREATE|DELETE|DROP|EXEC|EXECUTE|FETCH|GRANT|INSERT|PERFORM|PREPARE|REVOKE|ROLLBACK|SELECT|UPDATE)\b
868
920
  lang.sql.tokens.commands.format cyan
@@ -870,6 +922,7 @@ lang.sql.tokens.data_types.case_insensitive \b(BIT|BOOLEAN|CHAR|CHARACTER|DATE|D
870
922
  lang.sql.tokens.data_types.format brown
871
923
  lang.sql.tokens.comments (--.*)
872
924
  lang.sql.tokens.comments.format 8 bold
925
+ lang.sql.comment_string --
873
926
  lang.sql.tokens.singlequoted_strings ('.*?[^\\]')
874
927
  lang.sql.tokens.singlequoted_strings.format green bold
875
928
  lang.sql.tokens.non_alphanum ([!@#$%\^&*()\[\]{}/?=+\-\\|,<.>;:])
@@ -895,6 +948,7 @@ lang.bash.indent.roundup true
895
948
  lang.bash.tabsize 4
896
949
  lang.bash.tokens.comments (^\s*#.*)
897
950
  lang.bash.tokens.comments.format 8 bold
951
+ lang.bash.comment_string #
898
952
  lang.bash.tokens.singlequoted_strings ('.*?[^\\]')
899
953
  lang.bash.tokens.singlequoted_strings.format green bold
900
954
  lang.bash.tokens.doublequoted_strings (\".*?[^\\]\")
@@ -920,6 +974,7 @@ lang.tcl.indent.roundup true
920
974
  lang.tcl.tabsize 4
921
975
  lang.tcl.tokens.comments (^\s*#.*)
922
976
  lang.tcl.tokens.comments.format 8 bold
977
+ lang.tcl.comment_string #
923
978
  lang.tcl.tokens.reserved_words \b(encoding|incr|pid|tcl_endOfWord|Tcl|eof|info|tcl_findLibrary|after|error|interp|pkg_mkIndex|tcl_startOfNextWord|append|eval|join|proc|tcl_startOfPreviousWord|array|exec|lappend|puts|tcl_wordBreakAfter|auto_execok|exit|lassign|pwd|tcl_wordBreakBefore|auto_import|expr|lindex|re_syntax|tcltest|auto_load|fblocked|linsert|read|tclvars|auto_mkindex|fconfigure|list|regexp|tell|auto_mkindex_old|fcopy|llength|registry|time|auto_qualify|file|load|regsub|trace|auto_reset|fileevent|lrange|rename|unknown|bgerror|filename|lrepeat|resource|unload|binary|flush|lreplace|return|unset|break|for|lsearch|scan|update|catch|foreach|lset|seek|uplevel|cd|format|lsort|set|upvar|clock|gets|memory|socket|variable|close|glob|msgcat|source|vwait|concat|global|namespace|split|while|continue|history|open|string|dde|http|package|subst|dict|if|parray|switch)\b
924
979
  lang.tcl.tokens.reserved_words.format white
925
980
  lang.tcl.tokens.non_alphanum ([!@#$%\^&*()\[\]{}/?=+\-\\|,<.>;:])
@@ -992,6 +1047,7 @@ lang.yaml.tokens.directive_indicator ^(%.*)
992
1047
  lang.yaml.tokens.directive_indicator.format 10
993
1048
  lang.yaml.tokens.comment_indicator (#.+)
994
1049
  lang.yaml.tokens.comment_indicator.format 8 bold
1050
+ lang.yaml.comment_string #
995
1051
  lang.yaml.tokens.anchor_indicator (&\w+)
996
1052
  lang.yaml.tokens.anchor_indicator.format red bold
997
1053
  lang.yaml.tokens.alias_indicator (\*\w+)
@@ -47,8 +47,8 @@ require 'diakonos/readline'
47
47
 
48
48
  module Diakonos
49
49
 
50
- VERSION = '0.8.5'
51
- LAST_MODIFIED = 'August 27, 2008'
50
+ VERSION = '0.8.6'
51
+ LAST_MODIFIED = 'October 31, 2008'
52
52
 
53
53
  DONT_ADJUST_ROW = false
54
54
  ADJUST_ROW = true
@@ -56,6 +56,8 @@ module Diakonos
56
56
  DONT_PROMPT_OVERWRITE = false
57
57
  DO_REDRAW = true
58
58
  DONT_REDRAW = false
59
+ QUIET = true
60
+ NOISY = false
59
61
 
60
62
  TAB = 9
61
63
  ENTER = 13
@@ -116,6 +118,8 @@ module Diakonos
116
118
  'closeFile',
117
119
  'close_code',
118
120
  'collapseWhitespace',
121
+ 'columnize',
122
+ 'comment_out',
119
123
  'copySelection',
120
124
  'copy_selection_to_klipper',
121
125
  'cursorBOF',
@@ -172,6 +176,7 @@ module Diakonos
172
176
  'paste_from_klipper',
173
177
  'playMacro',
174
178
  'popTag',
179
+ 'print_mapped_function',
175
180
  'printKeychain',
176
181
  'quit',
177
182
  'redraw',
@@ -185,6 +190,7 @@ module Diakonos
185
190
  'scrollUp',
186
191
  'searchAndReplace',
187
192
  'seek',
193
+ 'select_all',
188
194
  'select_block',
189
195
  'setBufferType',
190
196
  'setReadOnly',
@@ -198,9 +204,11 @@ module Diakonos
198
204
  'toggleMacroRecording',
199
205
  'toggleSelection',
200
206
  'toggleSessionSetting',
207
+ 'uncomment',
201
208
  'undo',
202
209
  'unindent',
203
- 'unundo'
210
+ 'unundo',
211
+ 'wrap_paragraph',
204
212
  ]
205
213
  LANG_TEXT = 'text'
206
214
 
@@ -215,16 +223,17 @@ class Diakonos
215
223
 
216
224
  def initialize( argv = [] )
217
225
  @diakonos_home = ( ( ENV[ 'HOME' ] or '' ) + '/.diakonos' ).subHome
218
- if not FileTest.exists? @diakonos_home
219
- Dir.mkdir @diakonos_home
220
- end
226
+ mkdir @diakonos_home
221
227
  @script_dir = "#{@diakonos_home}/scripts"
222
- if not FileTest.exists? @script_dir
223
- Dir.mkdir @script_dir
224
- end
228
+ mkdir @script_dir
229
+
230
+ init_help
231
+
225
232
  @debug = File.new( "#{@diakonos_home}/debug.log", 'w' )
226
233
  @list_filename = @diakonos_home + '/listing.txt'
227
234
  @diff_filename = @diakonos_home + '/text.diff'
235
+ @help_filename = "#{@help_dir}/about-help.dhf"
236
+ @error_filename = "#{@diakonos_home}/diakonos.err"
228
237
 
229
238
  @files = Array.new
230
239
  @read_only_files = Array.new
@@ -265,46 +274,63 @@ class Diakonos
265
274
  @iterated_choice = nil
266
275
  @choice_iterations = 0
267
276
  @there_was_non_movement = false
277
+ @status_vars = Hash.new
268
278
 
269
279
  # Readline histories
270
280
  @rlh_general = Array.new
271
281
  @rlh_files = Array.new
272
282
  @rlh_search = Array.new
273
283
  @rlh_shell = Array.new
284
+ @rlh_help = Array.new
285
+ end
286
+
287
+ def mkdir( dir )
288
+ if not FileTest.exists? dir
289
+ Dir.mkdir dir
290
+ end
274
291
  end
275
292
 
276
293
  def parseOptions( argv )
294
+ @post_load_script = ""
277
295
  while argv.length > 0
278
296
  arg = argv.shift
279
297
  case arg
280
- when '-h', '--help'
281
- printUsage
282
- exit 1
283
- when '-ro'
284
- filename = argv.shift
285
- if filename == nil
286
- printUsage
287
- exit 1
288
- else
289
- @read_only_files.push filename
290
- end
291
- when '-c', '--config'
292
- @config_filename = argv.shift
293
- if @config_filename == nil
294
- printUsage
295
- exit 1
296
- end
297
- when '-e', '--execute'
298
- post_load_script = argv.shift
299
- if post_load_script == nil
300
- printUsage
301
- exit 1
302
- else
303
- @post_load_script = post_load_script
304
- end
305
- else
306
- # a name of a file to open
307
- @files.push arg
298
+ when '-h', '--help'
299
+ printUsage
300
+ exit 1
301
+ when '-ro'
302
+ filename = argv.shift
303
+ if filename == nil
304
+ printUsage
305
+ exit 1
306
+ else
307
+ @read_only_files.push filename
308
+ end
309
+ when '-c', '--config'
310
+ @config_filename = argv.shift
311
+ if @config_filename == nil
312
+ printUsage
313
+ exit 1
314
+ end
315
+ when '-e', '--execute'
316
+ post_load_script = argv.shift
317
+ if post_load_script.nil?
318
+ printUsage
319
+ exit 1
320
+ else
321
+ @post_load_script << "\n#{post_load_script}"
322
+ end
323
+ when '-m', '--open-matching'
324
+ regexp = argv.shift
325
+ files = `egrep -rl '#{regexp}' *`.split( /\n/ )
326
+ if files.any?
327
+ @files.concat files
328
+ script = "\nfind 'down', CASE_SENSITIVE, '#{regexp}'"
329
+ @post_load_script << script
330
+ end
331
+ else
332
+ # a name of a file to open
333
+ @files.push arg
308
334
  end
309
335
  end
310
336
  end
@@ -313,12 +339,64 @@ class Diakonos
313
339
  def printUsage
314
340
  puts "Usage: #{$0} [options] [file] [file...]"
315
341
  puts "\t--help\tDisplay usage"
316
- puts "\t-ro <file>\tLoad file as read-only"
317
342
  puts "\t-c <config file>\tLoad this config file instead of ~/.diakonos/diakonos.conf"
318
343
  puts "\t-e, --execute <Ruby code>\tExecute Ruby code (such as Diakonos commands) after startup"
344
+ puts "\t-m, --open-matching <regular expression>\tOpen all matching files under current directory"
345
+ puts "\t-ro <file>\tLoad file as read-only"
319
346
  end
320
347
  protected :printUsage
321
348
 
349
+ def init_help
350
+ @base_help_dir = "#{@diakonos_home}/help"
351
+ mkdir @base_help_dir
352
+
353
+ @help_dir = "#{@diakonos_home}/help/#{VERSION}"
354
+ if not File.exist?( @help_dir )
355
+ puts "Help files for this Diakonos version were not found (#{@help_dir})."
356
+
357
+ $stdout.puts "Would you like to download the help files right now from the Diakonos website? (y/n)"; $stdout.flush
358
+ answer = $stdin.gets
359
+ case answer
360
+ when /^y/i
361
+ if not fetch_help
362
+ $stderr.puts "Failed to get help for version #{VERSION}."
363
+ end
364
+ end
365
+
366
+ if not FileTest.exists?( @help_dir ) or Dir[ "#{@help_dir}/*" ].size == 0
367
+ $stderr.puts "Terminating..."
368
+ exit 1
369
+ end
370
+ end
371
+
372
+ @help_tags = `grep -h Tags #{@help_dir}/* | cut -d ' ' -f 2-`.split.uniq
373
+ end
374
+
375
+ def fetch_help
376
+ require 'open-uri'
377
+ success = false
378
+ puts "Fetching help documents for version #{VERSION}..."
379
+
380
+ filename = "diakonos-help-#{VERSION}.tar.gz"
381
+ uri = "http://purepistos.net/diakonos/#{filename}"
382
+ tarball = "#{@base_help_dir}/#{filename}"
383
+ begin
384
+ open( uri ) do |http|
385
+ bytes = http.read
386
+ File.open( tarball, 'w' ) do |f|
387
+ f.print bytes
388
+ end
389
+ end
390
+ mkdir @help_dir
391
+ `tar zxf #{tarball} -C #{@base_help_dir}`
392
+ success = true
393
+ rescue OpenURI::HTTPError => e
394
+ $stderr.puts "Failed to fetch from #{uri} ."
395
+ end
396
+
397
+ success
398
+ end
399
+
322
400
  def initializeDisplay
323
401
  if @win_main != nil
324
402
  @win_main.close
@@ -400,7 +478,7 @@ class Diakonos
400
478
  $stderr.puts "Failed to fetch from #{location}."
401
479
  end
402
480
 
403
- return found
481
+ found
404
482
  end
405
483
 
406
484
  def loadConfiguration
@@ -515,13 +593,13 @@ class Diakonos
515
593
  keystrokes = Array.new
516
594
  keystrings.split( /\s+/ ).each do |ks_str|
517
595
  code = ks_str.keyCode
518
- if code != nil
596
+ if code
519
597
  keystrokes.concat code
520
598
  else
521
599
  puts "unknown keystring: #{ks_str}"
522
600
  end
523
601
  end
524
- if function_and_args == nil
602
+ if function_and_args.nil?
525
603
  @keychains.deleteKeyPath( keystrokes )
526
604
  else
527
605
  function, function_args = function_and_args.split( /\s+/, 2 )
@@ -603,7 +681,8 @@ class Diakonos
603
681
  end
604
682
  when "context.visible", "context.combined", "eof_newline", "view.nonfilelines.visible",
605
683
  /^lang\.(.+?)\.indent\.(?:auto|roundup|using_tabs|closers)$/,
606
- "found_cursor_start", "convert_tabs", 'delete_newline_on_delete_to_eol'
684
+ "found_cursor_start", "convert_tabs", 'delete_newline_on_delete_to_eol',
685
+ 'suppress_welcome'
607
686
  @settings[ command ] = arg.to_b
608
687
  when "context.format", "context.separator.format", "status.format"
609
688
  @settings[ command ] = arg.toFormatting
@@ -612,12 +691,16 @@ class Diakonos
612
691
  when "context.separator", "status.left", "status.right", "status.filler",
613
692
  "status.modified_str", "status.unnamed_str", "status.selecting_str",
614
693
  "status.read_only_str", /^lang\..+?\.indent\.ignore\.charset$/,
615
- /^lang\.(.+?)\.tokens\.([^.]+)\.change_to$/, "view.nonfilelines.character",
694
+ /^lang\.(.+?)\.tokens\.([^.]+)\.change_to$/,
695
+ /^lang\.(.+?)\.column_delimiters$/,
696
+ "view.nonfilelines.character",
616
697
  'interaction.blink_string', 'diff_command'
617
698
  @settings[ command ] = arg
699
+ when /^lang\..+?\.comment_(?:close_)?string$/
700
+ @settings[ command ] = arg.gsub( /^["']|["']$/, '' )
618
701
  when "status.vars"
619
702
  @settings[ command ] = arg.split( /\s+/ )
620
- when /^lang\.(.+?)\.indent\.size$/, /^lang\.(.+?)\.tabsize$/
703
+ when /^lang\.(.+?)\.indent\.size$/, /^lang\.(.+?)\.(?:tabsize|wrap_margin)$/
621
704
  @settings[ command ] = arg.to_i
622
705
  when "context.max_levels", "context.max_segment_width", "max_clips", "max_undo_lines",
623
706
  "view.margin.x", "view.margin.y", "view.scroll_amount", "view.lookback"
@@ -687,8 +770,8 @@ class Diakonos
687
770
  @debug.flush
688
771
  end
689
772
 
690
- def registerProc( proc, hook_name, priority = 0 )
691
- @hooks[ hook_name ] << { :proc => proc, :priority => priority }
773
+ def register_proc( the_proc, hook_name, priority = 0 )
774
+ @hooks[ hook_name ] << { :proc => the_proc, :priority => priority }
692
775
  end
693
776
 
694
777
  def clearNonMovementFlag
@@ -705,7 +788,7 @@ class Diakonos
705
788
  if @settings[ "context.visible" ] and not @settings[ "context.combined" ]
706
789
  retval = retval - 1
707
790
  end
708
- return retval
791
+ retval
709
792
  end
710
793
 
711
794
  def main_window_width
@@ -716,8 +799,10 @@ class Diakonos
716
799
  initializeDisplay
717
800
 
718
801
  @hooks = {
719
- :after_save => [],
720
- :after_startup => [],
802
+ :after_buffer_switch => [],
803
+ :after_open => [],
804
+ :after_save => [],
805
+ :after_startup => [],
721
806
  }
722
807
  Dir[ "#{@script_dir}/*" ].each do |script|
723
808
  begin
@@ -751,113 +836,146 @@ class Diakonos
751
836
  end
752
837
 
753
838
  if num_opened > 0
754
- switchToBufferNumber 1
755
-
756
- updateStatusLine
757
- updateContextLine
758
-
759
- if @post_load_script != nil
760
- eval @post_load_script
761
- end
762
-
763
- runHookProcs( :after_startup )
764
-
765
- begin
766
- # Main keyboard loop.
767
- while not @quitting
768
- processKeystroke
769
- @win_main.refresh
770
- end
771
- rescue SignalException => e
772
- debugLog "Terminated by signal (#{e.message})"
773
- end
774
-
775
- @debug.close
839
+ switchToBufferNumber 1
840
+
841
+ updateStatusLine
842
+ updateContextLine
843
+
844
+ if @post_load_script != nil
845
+ eval @post_load_script
846
+ end
847
+
848
+ runHookProcs :after_startup
849
+
850
+ if not @settings[ 'suppress_welcome' ]
851
+ openFile "#{@help_dir}/welcome.dhf"
852
+ end
853
+
854
+ begin
855
+ # Main keyboard loop.
856
+ while not @quitting
857
+ processKeystroke
858
+ @win_main.refresh
859
+ end
860
+ rescue SignalException => e
861
+ debugLog "Terminated by signal (#{e.message})"
862
+ end
863
+
864
+ @debug.close
865
+ end
866
+ end
867
+
868
+ def capture_keychain( c, context )
869
+ if c == ENTER
870
+ @capturing_keychain = false
871
+ @current_buffer.deleteSelection
872
+ str = context.to_keychain_s.strip
873
+ @current_buffer.insertString str
874
+ cursorRight( Buffer::STILL_TYPING, str.length )
875
+ else
876
+ keychain_pressed = context.concat [ c ]
877
+
878
+ function_and_args = @keychains.getLeaf( keychain_pressed )
879
+
880
+ if function_and_args
881
+ function, args = function_and_args
882
+ end
883
+
884
+ partial_keychain = @keychains.getNode( keychain_pressed )
885
+ if partial_keychain
886
+ setILine( "Part of existing keychain: " + keychain_pressed.to_keychain_s + "..." )
887
+ else
888
+ setILine keychain_pressed.to_keychain_s + "..."
776
889
  end
890
+ processKeystroke( keychain_pressed )
891
+ end
892
+ end
893
+
894
+ def capture_mapping( c, context )
895
+ if c == ENTER
896
+ @capturing_mapping = false
897
+ @current_buffer.deleteSelection
898
+ setILine
899
+ else
900
+ keychain_pressed = context.concat [ c ]
901
+
902
+ function_and_args = @keychains.getLeaf( keychain_pressed )
903
+
904
+ if function_and_args
905
+ function, args = function_and_args
906
+ setILine "#{keychain_pressed.to_keychain_s.strip} -> #{function}( #{args} )"
907
+ else
908
+ partial_keychain = @keychains.getNode( keychain_pressed )
909
+ if partial_keychain
910
+ setILine( "Several mappings start with: " + keychain_pressed.to_keychain_s + "..." )
911
+ processKeystroke( keychain_pressed )
912
+ else
913
+ setILine "There is no mapping for " + keychain_pressed.to_keychain_s
914
+ end
915
+ end
916
+ end
777
917
  end
778
918
 
779
919
  # context is an array of characters (bytes) which are keystrokes previously
780
920
  # typed (in a chain of keystrokes)
781
921
  def processKeystroke( context = [] )
782
- c = @win_main.getch
922
+ c = @win_main.getch
783
923
 
784
- if @capturing_keychain
785
- if c == ENTER
786
- @capturing_keychain = false
787
- @current_buffer.deleteSelection
788
- str = context.to_keychain_s.strip
789
- @current_buffer.insertString str
790
- cursorRight( Buffer::STILL_TYPING, str.length )
791
- else
792
- keychain_pressed = context.concat [ c ]
793
-
794
- function_and_args = @keychains.getLeaf( keychain_pressed )
795
-
796
- if function_and_args != nil
797
- function, args = function_and_args
798
- end
799
-
800
- partial_keychain = @keychains.getNode( keychain_pressed )
801
- if partial_keychain != nil
802
- setILine( "Part of existing keychain: " + keychain_pressed.to_keychain_s + "..." )
803
- else
804
- setILine keychain_pressed.to_keychain_s + "..."
805
- end
806
- processKeystroke( keychain_pressed )
807
- end
808
- else
924
+ if @capturing_keychain
925
+ capture_keychain c, context
926
+ elsif @capturing_mapping
927
+ capture_mapping c, context
928
+ else
809
929
 
810
- if context.empty?
811
- if c > 31 and c < 255 and c != BACKSPACE
812
- if @macro_history != nil
813
- @macro_history.push "typeCharacter #{c}"
814
- end
815
- if not @there_was_non_movement
816
- @there_was_non_movement = true
817
- end
818
- typeCharacter c
819
- return
820
- end
821
- end
822
- keychain_pressed = context.concat [ c ]
823
-
824
- function_and_args = @keychains.getLeaf( keychain_pressed )
930
+ if context.empty?
931
+ if c > 31 and c < 255 and c != BACKSPACE
932
+ if @macro_history
933
+ @macro_history.push "typeCharacter #{c}"
934
+ end
935
+ @there_was_non_movement = true
936
+ typeCharacter c
937
+ return
938
+ end
939
+ end
940
+ keychain_pressed = context.concat [ c ]
825
941
 
826
- if function_and_args != nil
827
- function, args = function_and_args
828
- setILine if not @settings[ "context.combined" ]
829
-
830
- if args != nil
831
- to_eval = "#{function}( #{args} )"
832
- else
833
- to_eval = function
834
- end
835
-
836
- if @macro_history != nil
837
- @macro_history.push to_eval
838
- end
839
-
840
- begin
841
- eval to_eval, nil, "eval"
842
- @last_commands << to_eval unless to_eval == "repeatLast"
843
- if not @there_was_non_movement
844
- @there_was_non_movement = ( not to_eval.movement? )
845
- end
846
- rescue Exception => e
847
- debugLog e.message
848
- debugLog e.backtrace.join( "\n\t" )
849
- showException e
850
- end
851
- else
852
- partial_keychain = @keychains.getNode( keychain_pressed )
853
- if partial_keychain != nil
854
- setILine( keychain_pressed.to_keychain_s + "..." )
855
- processKeystroke( keychain_pressed )
856
- else
857
- setILine "Nothing assigned to #{keychain_pressed.to_keychain_s}"
858
- end
859
- end
942
+ function_and_args = @keychains.getLeaf( keychain_pressed )
943
+
944
+ if function_and_args
945
+ function, args = function_and_args
946
+ setILine if not @settings[ "context.combined" ]
947
+
948
+ if args
949
+ to_eval = "#{function}( #{args} )"
950
+ else
951
+ to_eval = function
952
+ end
953
+
954
+ if @macro_history
955
+ @macro_history.push to_eval
956
+ end
957
+
958
+ begin
959
+ eval to_eval, nil, "eval"
960
+ @last_commands << to_eval unless to_eval == "repeatLast"
961
+ if not @there_was_non_movement
962
+ @there_was_non_movement = ( not to_eval.movement? )
963
+ end
964
+ rescue Exception => e
965
+ debugLog e.message
966
+ debugLog e.backtrace.join( "\n\t" )
967
+ showException e
968
+ end
969
+ else
970
+ partial_keychain = @keychains.getNode( keychain_pressed )
971
+ if partial_keychain
972
+ setILine( keychain_pressed.to_keychain_s + "..." )
973
+ processKeystroke( keychain_pressed )
974
+ else
975
+ setILine "Nothing assigned to #{keychain_pressed.to_keychain_s}"
976
+ end
860
977
  end
978
+ end
861
979
  end
862
980
  protected :processKeystroke
863
981
 
@@ -868,7 +986,7 @@ class Diakonos
868
986
  @win_interaction.addstr( "%-#{Curses::cols}s" % string )
869
987
  @win_interaction.refresh
870
988
  Curses::curs_set 1
871
- return string.length
989
+ string.length
872
990
  end
873
991
 
874
992
  def showClips
@@ -883,22 +1001,27 @@ class Diakonos
883
1001
  end
884
1002
 
885
1003
  def switchTo( buffer )
886
- switched = false
887
- if buffer
888
- @buffer_stack -= [ @current_buffer ]
889
- if @current_buffer
890
- @buffer_stack.push @current_buffer
891
- end
892
- @current_buffer = buffer
893
- updateStatusLine
894
- updateContextLine
895
- buffer.display
896
- switched = true
1004
+ switched = false
1005
+ if buffer
1006
+ @buffer_stack -= [ @current_buffer ]
1007
+ if @current_buffer
1008
+ @buffer_stack.push @current_buffer
897
1009
  end
898
-
899
- switched
1010
+ @current_buffer = buffer
1011
+ runHookProcs( :after_buffer_switch, buffer )
1012
+ updateStatusLine
1013
+ updateContextLine
1014
+ buffer.display
1015
+ switched = true
1016
+ end
1017
+
1018
+ switched
900
1019
  end
901
1020
  protected :switchTo
1021
+
1022
+ def set_status_variable( identifier, value )
1023
+ @status_vars[ identifier ] = value
1024
+ end
902
1025
 
903
1026
  def buildStatusLine( truncation = 0 )
904
1027
  var_array = Array.new
@@ -937,6 +1060,8 @@ class Diakonos
937
1060
  end
938
1061
  when "type"
939
1062
  var_array.push @current_buffer.original_language
1063
+ when /^@/
1064
+ var_array.push @status_vars[ var ]
940
1065
  end
941
1066
  end
942
1067
  str = nil
@@ -1027,32 +1152,30 @@ class Diakonos
1027
1152
  end
1028
1153
 
1029
1154
  def displayDequeue
1030
- @display_queue_mutex.synchronize do
1031
- if @display_queue != nil
1032
- Thread.new( @display_queue ) do |b|
1033
- @display_mutex.lock
1034
- @display_mutex.unlock
1035
- b.display
1036
- end
1037
- @display_queue = nil
1038
- end
1155
+ @display_queue_mutex.synchronize do
1156
+ if @display_queue
1157
+ Thread.new( @display_queue ) do |b|
1158
+ @display_mutex.lock
1159
+ @display_mutex.unlock
1160
+ b.display
1161
+ end
1162
+ @display_queue = nil
1039
1163
  end
1164
+ end
1040
1165
  end
1041
1166
 
1042
1167
  # completion_array is the array of strings that tab completion can use
1043
- def getUserInput( prompt, history = @rlh_general, initial_text = "", completion_array = nil )
1168
+ def getUserInput( prompt, history = @rlh_general, initial_text = "", completion_array = nil, &block )
1044
1169
  if @playing_macro
1045
1170
  retval = @macro_input_history.shift
1046
1171
  else
1047
- pos = setILine prompt
1048
- @win_interaction.setpos( 0, pos )
1049
- retval = Readline.new( self, @win_interaction, initial_text, completion_array, history ).readline
1050
- if @macro_history != nil
1172
+ retval = Readline.new( self, @win_interaction, prompt, initial_text, completion_array, history, &block ).readline
1173
+ if @macro_history
1051
1174
  @macro_input_history.push retval
1052
1175
  end
1053
1176
  setILine
1054
1177
  end
1055
- return retval
1178
+ retval
1056
1179
  end
1057
1180
 
1058
1181
  def getLanguageFromName( name )
@@ -1063,7 +1186,7 @@ class Diakonos
1063
1186
  break
1064
1187
  end
1065
1188
  end
1066
- return retval
1189
+ retval
1067
1190
  end
1068
1191
 
1069
1192
  def getLanguageFromShaBang( first_line )
@@ -1074,12 +1197,12 @@ class Diakonos
1074
1197
  break
1075
1198
  end
1076
1199
  end
1077
- return retval
1200
+ retval
1078
1201
  end
1079
1202
 
1080
1203
  def showException( e, probable_causes = [ "Unknown" ] )
1081
1204
  begin
1082
- File.open( @diakonos_home + "/diakonos.err", "w" ) do |f|
1205
+ File.open( @error_filename, "w" ) do |f|
1083
1206
  f.puts "Diakonos Error:"
1084
1207
  f.puts
1085
1208
  f.puts e.message
@@ -1096,7 +1219,7 @@ class Diakonos
1096
1219
  f.puts "----------------------------------------------------"
1097
1220
  f.puts e.backtrace
1098
1221
  end
1099
- openFile( @diakonos_home + "/diakonos.err" )
1222
+ openFile( @error_filename )
1100
1223
  rescue Exception => e2
1101
1224
  debugLog "EXCEPTION: #{e.message}"
1102
1225
  debugLog "\t#{e.backtrace}"
@@ -1200,7 +1323,7 @@ class Diakonos
1200
1323
  retval.gsub!( /\$s/, text_filename )
1201
1324
  end
1202
1325
 
1203
- return retval
1326
+ retval
1204
1327
  end
1205
1328
 
1206
1329
  def showMessage( message, non_interaction_duration = @settings[ 'interaction.choice_delay' ] )
@@ -1310,7 +1433,7 @@ class Diakonos
1310
1433
  @do_display = false
1311
1434
  end
1312
1435
 
1313
- return retval
1436
+ retval
1314
1437
  end
1315
1438
 
1316
1439
  def startRecordingMacro( name = nil )
@@ -1382,6 +1505,9 @@ class Diakonos
1382
1505
  def showing_list?
1383
1506
  @list_buffer
1384
1507
  end
1508
+ def list_item_selected?
1509
+ @list_buffer and @list_buffer.selecting?
1510
+ end
1385
1511
  def current_list_item
1386
1512
  if @list_buffer
1387
1513
  @list_buffer.select_current_line
@@ -1407,6 +1533,14 @@ class Diakonos
1407
1533
  end
1408
1534
  end
1409
1535
 
1536
+ def open_help_buffer
1537
+ @help_buffer = openFile( @help_filename )
1538
+ end
1539
+ def close_help_buffer
1540
+ closeFile @help_buffer
1541
+ @help_buffer = nil
1542
+ end
1543
+
1410
1544
  def runHookProcs( hook_id, *args )
1411
1545
  @hooks[ hook_id ].each do |hook_proc|
1412
1546
  hook_proc[ :proc ].call( *args )
@@ -1567,12 +1701,29 @@ class Diakonos
1567
1701
  end
1568
1702
 
1569
1703
  def collapseWhitespace
1570
- @current_buffer.collapseWhitespace
1704
+ @current_buffer.collapseWhitespace
1705
+ end
1706
+
1707
+ def columnize( delimiter = nil, num_spaces_padding = 0 )
1708
+ if delimiter.nil?
1709
+ delimiter = getUserInput(
1710
+ "Column delimiter (regexp): ",
1711
+ @rlh_general,
1712
+ @settings[ "lang.#{@current_buffer.original_language}.column_delimiters" ] || ''
1713
+ )
1714
+ end
1715
+ if delimiter and num_spaces_padding
1716
+ @current_buffer.columnize Regexp.new( delimiter ), num_spaces_padding
1717
+ end
1718
+ end
1719
+
1720
+ def comment_out
1721
+ @current_buffer.comment_out
1571
1722
  end
1572
1723
 
1573
1724
  def copySelection
1574
- @clipboard.addClip @current_buffer.copySelection
1575
- removeSelection
1725
+ @clipboard.addClip @current_buffer.copySelection
1726
+ removeSelection
1576
1727
  end
1577
1728
 
1578
1729
  def copy_selection_to_klipper
@@ -1740,46 +1891,82 @@ class Diakonos
1740
1891
  end
1741
1892
 
1742
1893
  def find( dir_str = "down", case_sensitive = CASE_INSENSITIVE, regexp_source_ = nil, replacement = nil )
1743
- if regexp_source_ == nil
1744
- if @current_buffer.changing_selection
1745
- selected_text = @current_buffer.copySelection[ 0 ]
1746
- end
1747
- regexp_source = getUserInput( "Search regexp: ", @rlh_search, ( selected_text or "" ) )
1748
- else
1749
- regexp_source = regexp_source_
1894
+ direction = dir_str.toDirection
1895
+ if regexp_source_.nil?
1896
+ if @current_buffer.changing_selection
1897
+ selected_text = @current_buffer.copySelection[ 0 ]
1750
1898
  end
1751
-
1752
- if regexp_source != nil
1753
- direction = dir_str.toDirection
1754
- rs_array = regexp_source.newlineSplit
1755
- regexps = Array.new
1756
- begin
1757
- rs_array.each do |regexp_source|
1758
- if not case_sensitive
1759
- regexps.push Regexp.new( regexp_source, Regexp::IGNORECASE )
1760
- else
1761
- regexps.push Regexp.new( regexp_source )
1762
- end
1763
- end
1764
- rescue Exception => e
1765
- exception_thrown = true
1766
- rs_array.each do |regexp_source|
1767
- if not case_sensitive
1768
- regexps.push Regexp.new( Regexp.escape( regexp_source ), Regexp::IGNORECASE )
1769
- else
1770
- regexps.push Regexp.new( Regexp.escape( regexp_source ) )
1771
- end
1772
- end
1773
- end
1774
- if replacement == ASK_REPLACEMENT
1775
- replacement = getUserInput( "Replace with: ", @rlh_search )
1776
- end
1777
-
1778
- setILine( "Searching literally; #{e.message}" ) if exception_thrown
1779
-
1780
- @current_buffer.find( regexps, direction, replacement )
1781
- @last_search_regexps = regexps
1899
+ starting_row, starting_col = @current_buffer.last_row, @current_buffer.last_col
1900
+
1901
+ regexp_source = getUserInput(
1902
+ "Search regexp: ",
1903
+ @rlh_search,
1904
+ ( selected_text or "" )
1905
+ ) { |input|
1906
+ if input.length > 1
1907
+ find_ direction, case_sensitive, input, nil, starting_row, starting_col, QUIET
1908
+ else
1909
+ @current_buffer.removeSelection Buffer::DONT_DISPLAY
1910
+ @current_buffer.clearMatches Buffer::DO_DISPLAY
1911
+ end
1912
+ }
1913
+ else
1914
+ regexp_source = regexp_source_
1915
+ end
1916
+
1917
+ if regexp_source
1918
+ find_ direction, case_sensitive, regexp_source, replacement, starting_row, starting_col, NOISY
1919
+ elsif starting_row and starting_col
1920
+ @current_buffer.clearMatches
1921
+ @current_buffer.cursorTo starting_row, starting_col
1922
+ end
1923
+ end
1924
+
1925
+ # Worker method for find function.
1926
+ def find_( direction, case_sensitive, regexp_source, replacement, starting_row, starting_col, quiet )
1927
+ return if( regexp_source.nil? or regexp_source.empty? )
1928
+
1929
+ rs_array = regexp_source.newlineSplit
1930
+ regexps = Array.new
1931
+ exception_thrown = nil
1932
+
1933
+ rs_array.each do |source|
1934
+ begin
1935
+ warning_verbosity = $VERBOSE
1936
+ $VERBOSE = nil
1937
+ regexps << Regexp.new(
1938
+ source,
1939
+ case_sensitive ? nil : Regexp::IGNORECASE
1940
+ )
1941
+ $VERBOSE = warning_verbosity
1942
+ rescue RegexpError => e
1943
+ if not exception_thrown
1944
+ exception_thrown = e
1945
+ source = Regexp.escape( source )
1946
+ retry
1947
+ else
1948
+ raise e
1949
+ end
1782
1950
  end
1951
+ end
1952
+
1953
+ if replacement == ASK_REPLACEMENT
1954
+ replacement = getUserInput( "Replace with: ", @rlh_search )
1955
+ end
1956
+
1957
+ if exception_thrown and not quiet
1958
+ setILine( "Searching literally; #{exception_thrown.message}" )
1959
+ end
1960
+
1961
+ @current_buffer.find(
1962
+ regexps,
1963
+ :direction => direction,
1964
+ :replacement => replacement,
1965
+ :starting_row => starting_row,
1966
+ :starting_col => starting_col,
1967
+ :quiet => quiet
1968
+ )
1969
+ @last_search_regexps = regexps
1783
1970
  end
1784
1971
 
1785
1972
  def findAgain( dir_str = nil )
@@ -1806,8 +1993,8 @@ class Diakonos
1806
1993
  end
1807
1994
  if search_term != nil
1808
1995
  direction = dir_str.toDirection
1809
- regexp = Regexp.new( Regexp.escape( search_term ) )
1810
- @current_buffer.find( regexp, direction )
1996
+ regexp = [ Regexp.new( Regexp.escape( search_term ) ) ]
1997
+ @current_buffer.find( regexp, :direction => direction )
1811
1998
  @last_search_regexps = regexp
1812
1999
  end
1813
2000
  end
@@ -1909,29 +2096,106 @@ class Diakonos
1909
2096
  goToTag @current_buffer.wordUnderCursor
1910
2097
  end
1911
2098
 
1912
- def help
1913
- help_filename = @diakonos_home + "/diakonos.help"
1914
- File.open( help_filename, "w" ) do |help_file|
1915
- sorted_keychains = @keychains.paths_and_leaves.sort { |a,b|
1916
- a[ :leaf ][ 0 ] <=> b[ :leaf ][ 0 ]
1917
- }
1918
- sorted_keychains.each do |keystrokes_and_function_and_args|
1919
- keystrokes = keystrokes_and_function_and_args[ :path ]
1920
- function, args = keystrokes_and_function_and_args[ :leaf ]
1921
- function_string = function.deep_clone
1922
- if args != nil and args.length > 0
1923
- function_string << "( #{args} )"
1924
- end
1925
- keychain_width = [ Curses::cols - function_string.length - 2, Curses::cols / 2 ].min
1926
- help_file.puts(
1927
- "%-#{keychain_width}s%s" % [
1928
- keystrokes.to_keychain_s,
1929
- function_string
1930
- ]
1931
- )
1932
- end
2099
+ def with_list_file
2100
+ File.open( @list_filename, "w" ) do |f|
2101
+ yield f
2102
+ end
2103
+ end
2104
+
2105
+ def matching_help_documents( str )
2106
+ docs = []
2107
+
2108
+ if str =~ %r{^/(.+)$}
2109
+ regexp = $1
2110
+ files = Dir[ "#{@help_dir}/*" ].select{ |f|
2111
+ File.open( f ) { |io| io.grep( /#{regexp}/i ) }.any?
2112
+ }
2113
+ else
2114
+ terms = str.gsub( /[^a-zA-Z0-9-]/, ' ' ).split.join( '|' )
2115
+ file_grep = `egrep -i -l '^Tags.*\\b(#{terms})\\b' #{@help_dir}/*`
2116
+ files = file_grep.split( /\s+/ )
2117
+ end
2118
+
2119
+ files.each do |file|
2120
+ File.open( file ) do |f|
2121
+ docs << ( "%-300s | %s" % [ f.gets.strip, file ] )
1933
2122
  end
1934
- openFile help_filename
2123
+ end
2124
+
2125
+ docs.sort { |a,b| a.gsub( /^# (?:an?|the) */i, '# ' ) <=> b.gsub( /^# (?:an?|the) */i, '# ' ) }
2126
+ end
2127
+
2128
+ def open_help_document( selected_string )
2129
+ help_file = selected_string.split( "| " )[ -1 ]
2130
+ if File.exist? help_file
2131
+ openFile help_file
2132
+ end
2133
+ end
2134
+
2135
+ def help( prefill = '' )
2136
+ open_help_buffer
2137
+ matching_docs = nil
2138
+
2139
+ selected = getUserInput(
2140
+ "Search terms: ",
2141
+ @rlh_help,
2142
+ prefill,
2143
+ @help_tags
2144
+ ) { |input|
2145
+ next if input.length < 3 and input[ 0..0 ] != '/'
2146
+
2147
+ matching_docs = matching_help_documents( input )
2148
+ with_list_file do |list|
2149
+ list.puts matching_docs.join( "\n" )
2150
+ end
2151
+
2152
+ openListBuffer
2153
+ }
2154
+
2155
+ close_help_buffer
2156
+
2157
+ case selected
2158
+ when /\|/
2159
+ open_help_document selected
2160
+ when nil
2161
+ # Help search aborted; do nothing
2162
+ else
2163
+ # Not a selected help document
2164
+ if matching_docs.nil? or matching_docs.empty?
2165
+ matching_docs = matching_help_documents( selected )
2166
+ end
2167
+
2168
+ case matching_docs.size
2169
+ when 1
2170
+ open_help_document matching_docs[ 0 ]
2171
+ when 0
2172
+ File.open( @error_filename, 'w' ) do |f|
2173
+ f.puts "There were no help documents matching your search."
2174
+ f.puts "(#{selected.strip})"
2175
+ end
2176
+ error_file = openFile @error_filename
2177
+
2178
+ choice = getChoice(
2179
+ "Send your search terms to purepistos.net to help improve Diakonos?",
2180
+ [ CHOICE_YES, CHOICE_NO ]
2181
+ )
2182
+ case choice
2183
+ when CHOICE_YES
2184
+ require 'net/http'
2185
+ require 'uri'
2186
+
2187
+ res = Net::HTTP.post_form(
2188
+ URI.parse( 'http://dh.purepistos.net/' ),
2189
+ { 'q' => selected }
2190
+ )
2191
+ # TODO: let them choose "never" and "always"
2192
+ end
2193
+
2194
+ closeFile error_file
2195
+ else
2196
+ help selected
2197
+ end
2198
+ end
1935
2199
  end
1936
2200
 
1937
2201
  def indent
@@ -1970,7 +2234,7 @@ class Diakonos
1970
2234
  end
1971
2235
 
1972
2236
  def list_buffers
1973
- File.open( @list_filename, "w" ) do |f|
2237
+ with_list_file do |f|
1974
2238
  f.puts @buffers.keys.map { |name| "#{name}\n" }.sort
1975
2239
  end
1976
2240
  openListBuffer
@@ -2084,6 +2348,7 @@ class Diakonos
2084
2348
 
2085
2349
  if do_open
2086
2350
  buffer = Buffer.new( self, filename, buffer_key, read_only )
2351
+ runHookProcs( :after_open, buffer )
2087
2352
  @buffers[ buffer_key ] = buffer
2088
2353
  if switchTo( buffer ) and line_number
2089
2354
  @current_buffer.goToLine( line_number, 0 )
@@ -2095,17 +2360,23 @@ class Diakonos
2095
2360
  end
2096
2361
 
2097
2362
  def openFileAsk
2098
- if @current_buffer != nil and @current_buffer.name != nil
2099
- path = File.expand_path( File.dirname( @current_buffer.name ) ) + "/"
2100
- file = getUserInput( "Filename: ", @rlh_files, path )
2101
- else
2102
- file = getUserInput( "Filename: ", @rlh_files )
2103
- end
2104
- if file != nil
2105
- openFile file
2106
- updateStatusLine
2107
- updateContextLine
2363
+ prefill = ''
2364
+
2365
+ if @current_buffer
2366
+ if @current_buffer.current_line =~ %r{/} and @current_buffer.current_line =~ %r{[/\w.]+}
2367
+ prefill = $&
2368
+ elsif @current_buffer.name
2369
+ prefill = File.expand_path( File.dirname( @current_buffer.name ) ) + "/"
2108
2370
  end
2371
+ end
2372
+
2373
+ file = getUserInput( "Filename: ", @rlh_files, prefill )
2374
+
2375
+ if file
2376
+ openFile file
2377
+ updateStatusLine
2378
+ updateContextLine
2379
+ end
2109
2380
  end
2110
2381
 
2111
2382
  def operateOnString(
@@ -2226,9 +2497,14 @@ class Diakonos
2226
2497
  end
2227
2498
  end
2228
2499
 
2500
+ def print_mapped_function
2501
+ @capturing_mapping = true
2502
+ setILine "Type any chain of keystrokes or key chords, or press Enter to stop."
2503
+ end
2504
+
2229
2505
  def printKeychain
2230
- @capturing_keychain = true
2231
- setILine "Type any chain of keystrokes or key chords, then press Enter..."
2506
+ @capturing_keychain = true
2507
+ setILine "Type any chain of keystrokes or key chords, then press Enter..."
2232
2508
  end
2233
2509
 
2234
2510
  def quit
@@ -2322,14 +2598,26 @@ class Diakonos
2322
2598
  end
2323
2599
  end
2324
2600
 
2601
+ def select_all
2602
+ @current_buffer.select_all
2603
+ end
2604
+
2325
2605
  def select_block( beginning = nil, ending = nil, including_ending = true )
2326
2606
  if beginning.nil?
2327
- beginning = Regexp.new( getUserInput( "Start at regexp: " ) )
2607
+ input = getUserInput( "Start at regexp: " )
2608
+ if input
2609
+ beginning = Regexp.new input
2610
+ end
2611
+ end
2612
+ if beginning and ending.nil?
2613
+ input = getUserInput( "End before regexp: " )
2614
+ if input
2615
+ ending = Regexp.new input
2616
+ end
2328
2617
  end
2329
- if ending.nil?
2330
- ending = Regexp.new( getUserInput( "End before regexp: " ) )
2618
+ if beginning and ending
2619
+ @current_buffer.select( beginning, ending, including_ending )
2331
2620
  end
2332
- @current_buffer.select( beginning, ending, including_ending )
2333
2621
  end
2334
2622
 
2335
2623
  def scrollDown
@@ -2386,17 +2674,17 @@ class Diakonos
2386
2674
  updateStatusLine
2387
2675
  end
2388
2676
 
2389
- def shell( command_ = nil )
2677
+ def shell( command_ = nil, result_filename = 'shell-result.txt' )
2390
2678
  if command_ == nil
2391
2679
  command = getUserInput( "Command: ", @rlh_shell )
2392
2680
  else
2393
2681
  command = command_
2394
2682
  end
2395
-
2396
- if command != nil
2683
+
2684
+ if command
2397
2685
  command = subShellVariables( command )
2398
2686
 
2399
- result_file = @diakonos_home + "/shell-result.txt"
2687
+ result_file = "#{@diakonos_home}/#{result_filename}"
2400
2688
  File.open( result_file , "w" ) do |f|
2401
2689
  f.puts command
2402
2690
  f.puts
@@ -2541,6 +2829,10 @@ class Diakonos
2541
2829
  end
2542
2830
  end
2543
2831
 
2832
+ def uncomment
2833
+ @current_buffer.uncomment
2834
+ end
2835
+
2544
2836
  def undo( buffer = @current_buffer )
2545
2837
  buffer.undo
2546
2838
  end
@@ -2567,6 +2859,10 @@ class Diakonos
2567
2859
  def unundo( buffer = @current_buffer )
2568
2860
  buffer.unundo
2569
2861
  end
2862
+
2863
+ def wrap_paragraph
2864
+ @current_buffer.wrap_paragraph
2865
+ end
2570
2866
  end
2571
2867
 
2572
2868
  end