Class: Notes

Inherits:
Object show all
Defined in:
lib/xiki/notes.rb

Defined Under Namespace

Classes: NotesBlock

Constant Summary collapse

LABEL_REGEX =
/(?:[a-zA-Z0-9 _-]+\) )?/
@@single_letter_abbrev =
{
"f"=>"fix",
"b"=>"borrow",
"i"=>"implement",
"d"=>"do",
"de"=>"delete",
"r"=>"rename",
"t"=>"todo",
"e"=>"extract",
"er"=>"error",
}

Class Method Summary collapse

Class Method Details

.apply_stylesObject



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/xiki/notes.rb', line 376

def self.apply_styles
  # Don't format quotes (it overrides the following formatting)
  Styles.clear

  # >... lines (headings)
  Styles.apply("^\\(>\\)\\(.*\n\\)", nil, :notes_h1_pipe, :notes_h1)

  Styles.apply("^\\(> \\)\\(.*\n\\)", nil, :notes_h1_pipe, :notes_h1)
  Styles.apply("^\\(>> \\)\\(.*\n\\)", nil, :notes_h2_pipe, :notes_h2)
  Styles.apply("^\\(= \\)\\(.*\n\\)", nil, :notes_h1_pipe, :notes_h1)
  Styles.apply("^\\(== \\)\\(.*\n\\)", nil, :notes_h2_pipe, :notes_h2)

  Styles.apply("^\\(>\\)\\( .+?: \\)\\(.+\n\\)", nil, :notes_h1_pipe, :notes_h1_label, :notes_h1)

  Styles.apply("^\\(> 20[0-9][0-9]-[0-9][0-9]-[0-9][0-9].*:\\)\\(.*\n\\)", nil, :notes_h1_agenda_pipe, :notes_h1_agenda)

  @@h1_styles.each do |k, v|
    l = k.to_s[/_..(.)$/, 1]
    next unless l
    Styles.apply("^\\(> #{l}\\)\\(\n\\| .*\n\\)", nil, "#{k}_pipe".to_sym, k)
    Styles.apply("^\\(>\\)\\( #{l} .+: \\)\\(.*\n\\)", nil, "#{k}_pipe".to_sym, "#{k}_label".to_sym, k)
  end

  # >>... lines
  #     Styles.apply("^\\(>>\\)\\(.*\\)", nil, :notes_h2_pipe, :notes_h2)
  Styles.apply("^\\(>>\\)\\(.*\n\\)", nil, :notes_h2_pipe, :notes_h2)

  # Commented
  Styles.apply("^\\(>> .+?: \\)\\(.+\n\\)", nil, :notes_h2_pipe, :notes_h2)

  # >>>... lines
  Styles.apply("^\\(>>>\\)\\(.*\n\\)", nil, :notes_h3_pipe, :notes_h3)

  # >>>... lines
  Styles.apply("^\\(>>>>\\)\\(.*\n\\)", nil, :notes_h4_pipe, :notes_h4)

  # - bullets with labels and comments
  Styles.apply("^[ \t]*\\([<+-]\\) \\([^/:\n]+:\\) ", nil, :ls_bullet, :notes_label)   # - hey: you
  Styles.apply("^[ \t]*\\([<+-]<*\\) \\([^(\n]+?)\\) ", nil, :ls_bullet, :notes_label)   # - hey) you

  Styles.apply("^[ \t]*\\([<+=-]<*\\) \\([^(\n]+)\\)$", nil, :ls_bullet, :notes_label)   # - hey)
  Styles.apply("^[ \t]*\\([<+=-]<*\\) \\(.+:\\)$", nil, :ls_bullet, :notes_label)   # - hey)

  #     Styles.apply("^[ \t]*\\(x\\)\\( \\)\\(.+\\)", nil, :notes_label, :variable, :strike)

  Styles.apply("^\\([ \t]*\\)\\([<+-]\\) \\(.+?:\\) +\\(|.*\n\\)", nil, :default, :ls_bullet, :notes_label, :ls_quote)
  Styles.apply("^\\([ \t]*\\)\\([<+-]\\) \\([^(\n]+?)\\) +\\(|.*\n\\)", nil, :default, :ls_bullet, :notes_label, :ls_quote)

  Styles.apply("^ +\\(!.*\n\\)", nil, :ls_quote)   # ^!... for commands

  # exclamation! / todo
  Styles.apply("^[ \t]*\\([<+-]\\) \\(.*!\\)$", nil, :ls_bullet, :notes_exclamation)
  Styles.apply("^ +\\(!\\+.*\n\\)", nil, :diff_green)   # Whole lines
  Styles.apply("^ +\\(!-.*\n\\)", nil, :diff_red)

  Styles.apply("\\(\(-\\)\\(.+?\\)\\(-\)\\)", nil, :diff_small, :diff_red, :diff_small)
  Styles.apply("\\(\(\\+\\)\\(.+?\\)\\(\\+\)\\)", nil, :diff_small, :diff_green, :diff_small)

  # google/
  Styles.apply "^ *\\(-?\\) ?\\(@?\\)\\(g\\)\\(o\\)\\(o\\)\\(g\\)\\(l\\)\\(e\\)\\(/\\)", nil, :ls_bullet, :ls_dir,
    :notes_blue, :notes_red, :notes_yellow, :notes_blue, :notes_green, :notes_red,
    :ls_dir

  Styles.apply "^hint/.+", :fade6

  Styles.apply "^[< ]*@? ?\\([%$&]\\) ", nil, :shell_prompt   # Colorize shell prompts

  Styles.apply("^ *\\(|`\\)\\(.*\n\\)", nil, :quote_heading_pipe, :dotsies_experimental)
  Styles.apply("^ *\\(|~\\)\\([^\n~]+\\)\\(~?\\)", nil, :quote_heading_pipe, :dotsies, :quote_heading_pipe)

end

.archiveObject



42
43
44
45
# File 'lib/xiki/notes.rb', line 42

def self.archive
  block = get_block
  block.archive
end

.as_navObject



626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# File 'lib/xiki/notes.rb', line 626

def self.as_nav

  prefix = Keys.prefix :clear=>true
  txt = ""
  if prefix == :u || prefix == :uu
    txt = Code.grab_containing_method
  end

  label = nil
  if prefix == 9
    label = Keys.input :prompt=>"label: ", :timed=>1
    label = "do" if label.blank?
    label = Notes.expand_if_action_abbrev(label) || label

    prefix = nil
  end

  if prefix == :uu   # up+up means add function and line
    txt << "\n#{Line.value}"
  elsif prefix != :u
    txt = View.txt_per_prefix prefix, :selection=>1, :default_is_line=>1, :just_txt=>1
  end

  # If file has bullet or ends with slash, grab path

  keep_tweeking = true
  if ! prefix && FileTree.handles?   # Grab tree
    txt = Tree.ancestors_indented :just_sub_tree=>1
    txt.sub! /^  /, '  - '
    keep_tweeking = false
  end

  file = View.file
  orig = Location.new

  if keep_tweeking
    if Search.fit_in_snippet(txt)   # Insert it in existing tree if there
      View << "    - #{label}:\n" if label
      return orig.go
    end
  else
    View.layout_files :no_blink=>1
  end

  # Make it quoted, unless already a quote
  if keep_tweeking && (txt !~ /\A([+-] |\/)/ || txt !~ /^ +/)   # If txt isn't already a tree, make it one
    txt = FileTree.snippet :txt=>txt, :file=>file
    txt.sub! /^    /, "    - #{label}:\n    " if label
  end

  # Else, add it to top...

  View.to_highest

  if prefix == 8
    if Line =~ /^>/
      Line.next
    end
    result = "#{txt}\n"
  else
    result = ">\n#{txt}\n"
  end

  View.<< result, :dont_move=>1

  orig.go
end

.as_todoObject



695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
# File 'lib/xiki/notes.rb', line 695

def self.as_todo
  prefix = Keys.prefix :clear=>1

  txt = nil

  # If method, make it Foo.bar method call
  line = Line.value

  if View.file =~ /_spec.rb/ && line =~ /^ *(it|describe) /
    return Specs.enter_as_rspec
  end

  buffer_name = $el.buffer_name
  file_name = View.file_name
  path = Xiki.path rescue nil

  if prefix.nil?   # So 1+ or numeric prefix just grab normally
    if buffer_name == "*ol"   # Make it into "foo = bar" format
      txt = line[/\) (.+)/, 1]
      txt.sub!(": ", " = ") if txt
      txt ||= line[/ *- (.+?) /, 1]

    elsif path && path.last =~ /(\w+)\.rb\/\| *def ([\w\.?]+)/
      clazz = $1
      method = $2
      clazz = TextUtil.camel_case clazz if method.slice! /^self\./
      txt = "#{clazz}.#{method}"

    elsif line =~ /^ +def (.+)/   # Make it into Foo.bar format
      method = $1
      clazz = file_name[/\w+/]
      clazz = TextUtil.camel_case clazz if method.slice! /^self\./

      txt = "#{clazz}.#{method}"

    elsif line =~ /^ *\|/   # Make it into Foo.bar format
      txt = line.sub /^ *\| ?/, ''
    elsif FileTree.handles?
      txt = Tree.dir
    elsif line =~ /(^ *[+-] |\/$)/   # Make it into Foo.bar format
      txt = Xiki.path.last
    end
  end

  txt ||= View.txt_per_prefix(prefix, :selection=>1, :just_txt=>1, :default_is_line=>1)
  txt.strip! if txt =~ /\A.+\n\z/   # Strip when only 1 linebreak

  options = prefix == :uu ? {:append=>1} : {}
  Search.move_to "$t", txt, options
end

.block(regex = "^> ") ⇒ Object



20
21
22
23
# File 'lib/xiki/notes.rb', line 20

def self.block regex="^> "
  left, after_header, right = View.block_positions regex
  View.txt after_header, right
end

.bullet(bullet_text = "- ") ⇒ Object



512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
# File 'lib/xiki/notes.rb', line 512

def self.bullet bullet_text="- "
  prefix = Keys.prefix :clear=>true

  if prefix == :u
    Move.forward if Line.at_right?
    return Tree.collapse
  end

  if prefix == :uu
    return Tree.collapse :replace_parent=>1
  end

  line = Line.value
  indent = Line.indent indent

  if line.present?   # If non-blank line
    Move.to_end if line =~ /^ / && View.column <= indent.length   # If just entered a bullet, go to end first

    Move.to_end if line =~ /^[+-] / && View.column <= 2   # If just entered a bullet, go to end first

    # If at beginning of line, just insert bullet
    return View.insert "- " if View.column == 0 && bullet_text == "- " && line !~ /^ /

    if View.cursor != Line.right
      Deletes.delete_whitespace
    end
    View.insert "\n"

    # Do simple case if quoted
    return View.<<("#{line[/^[ |#]*/]}  - ") if line =~ /^ *[|#]/

    # Do simple case if on heading
    return View.<<("- ") if line =~ /^>/
  end

  if prefix.is_a? Fixnum   # If numeric prefix, indent by n
    View.insert((" " * prefix) + bullet_text)
  else   # Get bullet indent of previous line
    prev = Line.value(0)
    prev_indent = prev[/^( *)/]

    # Indent further, unless it we're doing bullets and not following bullet
    prev_indent << "  " if line != "" && (bullet_text != "- " || prev =~ /^ *[+-]/ || prev !~ /^>/)
    prev_indent = "#{prev_indent}#{bullet_text}"
    View.insert prev_indent

    if prefix == :-
      View.insert "(): "
      Move.backward 3
    end
  end

  return if bullet_text == ""   # Don't indent rest if not using bullets (enter_junior)

  following_line = Line.value(2)
  return if following_line !~ /^ /   # Don't indent rest of lines if at left margin
  return if Line.matches /^[ -]*$/   # Exit if new bullet was blank

  indent = Line.indent

  return if indent.empty?   # Don't indent anything if new bullet wasn't indented

  cursor = View.cursor
  Line.next
  top = View.cursor

  # Find next line not indented underneath
  Search.forward "^ \\{0,#{indent.size-1}\\}\\($\\|[^ \n]\\)", :beginning=>true
  $el.indent_rigidly top, Line.left, 2
  View.cursor = cursor

end

.copy_blockObject



151
152
153
154
155
156
# File 'lib/xiki/notes.rb', line 151

def self.copy_block
  prefix = Keys.prefix
  block = get_block prefix == :u ? 2 : 1
  block.blink
  Clipboard.set("0", Keys.prefix_u ? block.text : block.content)
end

.cut_block(no_clipboard = false) ⇒ Object



140
141
142
143
144
145
146
147
148
149
# File 'lib/xiki/notes.rb', line 140

def self.cut_block no_clipboard=false
  block = get_block Keys.prefix

  block.blink

  unless no_clipboard
    Clipboard.set("0", block.content)
  end
  block.delete_content
end

.define_stylesObject



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/xiki/notes.rb', line 235

def self.define_styles

  return if ! $el

  # - foo (r): <here>
  Styles.define :notes_light_gray, :fg => "bbb"

  # - foo (r): <here>
  Styles.define :variable, :face => 'verdana'

  # - foo (r): <here>
  Styles.define :notes_label_parens,
    :fg => "bbb",
    :size => "-2",
    :face => 'arial'

  # |...
  h1_size = "+3"

  # Colors of "| ..." headings
  if Styles.dark_bg?   # If black bg
    @@h1_styles = {
      :notes_h1 =>"333",
      :notes_h1r=>"611",   # | r This will be red
      :notes_h1o=>"841",   # | o This will be orange
      :notes_h1y=>"871",
      :notes_h1e=>"363",
      :notes_h1g=>"363",
      :notes_h1b=>"678",
      :notes_h1p=>"636",
      :notes_h1m=>"622",
      :notes_h1x=>"345",
      :notes_h1t=>"055",
      }
  else
    # Colors of headings
    @@h1_styles = {
      :notes_h1 =>"aaa",
      :notes_h1r=>"b66",   # | r This will be red
      :notes_h1o=>"b83",   # | o This will be orange
      :notes_h1y=>"bb3",
      :notes_h1e=>"363",
      :notes_h1g=>"7b6",
      :notes_h1b=>"678",
      :notes_h1p=>"b8b",
      :notes_h1m=>"944",
      :notes_h1x=>"678",
      :notes_h1t=>"055",
      }
  end

  @@h1_styles.each do |k, v|
    pipe = v.gsub(/./) {|c| (c.to_i(16) + "3".to_i(16)).to_s(16)}
    label = v.gsub(/./) {|c| (c.to_i(16) + "6".to_i(16)).to_s(16)}
    Styles.define k,
      :face=>'arial', :size=>h1_size, :fg=>'ffffff', :bg=>v, :bold=> true
    Styles.define "#{k}_pipe".to_sym, :face=>'arial', :size=>h1_size, :fg=>pipe, :bg=>v, :bold=>true
    Styles.define "#{k}_label".to_sym, :face=>'arial', :size=>h1_size, :fg=>label, :bg=>v, :bold=>true
  end

  Styles.define :notes_h1_agenda_pipe, :face => 'arial', :size => h1_size, :fg => '88cc88', :bg => '336633', :bold =>  true
  Styles.define :notes_h1_agenda, :face => 'arial', :size => h1_size, :fg => 'ffffff', :bg => '336633', :bold => true

  # |||...
  Styles.define :notes_h3,
    :face => 'arial', :size => "-1",
    :fg => '999',#, :bg => "9999cc",
    :bold =>  true
  Styles.define :notes_h3_pipe,
    :face => 'arial', :size => "-1",
    :fg => '333'

  # ||||...
  Styles.define :notes_h4,
    :face => 'arial', :size => "-3",
    :fg => '55b',
    :bold =>  true
  Styles.define :notes_h4_pipe,
    :face => 'arial', :size => "-3",
    :fg => '224'


  if Styles.dark_bg?   # If black and white
    label_color = "e70"
  else
    label_color = "f70"
  end

  # Labels, emphasis
  Styles.define :notes_label,
    :face=>'arial black', :size=>"0",  # Mac
    #:face=>'courier', :size=>"0",  # Mac
    :fg=>label_color, :bold=>true

  Styles.define :notes_bullet_parens,
    :face => 'arial', :size => "-2",
    :fg => "ee7700", :bold => true

  # Strikethrough
  Styles.define(:strike, :strike=>true)

  # - <here> (r): foo
  Styles.define :notes_label_link,
    :face => 'verdana', :size => "-1",
    :fg => "66f",
    :bold => true, :underline => true

  Styles.define :notes_g, :fg=>"6cf", :face=>'arial black', :size=>"0", :bold=>true
  Styles.define :notes_blue, :fg=>"69f", :face=>'arial black', :size=>"0", :bold=>true
  Styles.define :notes_red, :fg=>"c55", :face=>'arial black', :size=>"0", :bold=>true
  Styles.define :notes_yellow, :fg=>"CC0", :face=>'arial black', :size=>"0", :bold=>true
  Styles.define :notes_green, :fg=>"3C3", :face=>'arial black', :size=>"0", :bold=>true


  if Styles.dark_bg?   # If black bg
    # >>...
    Styles.define :notes_h2, :face=>'arial', :size=>"-1", :fg=>'fff', :bg=>"333", :bold=>true
    Styles.define :notes_h2_pipe, :face=>'arial', :size=>"-1", :fg=>'555555', :bg=>"333333", :bold=> true
  else
    Styles.define :notes_h2, :face=>'arial', :size=>"-1", :fg=>'fff', :bg=>"999", :bold=>true
    Styles.define :notes_h2_pipe, :face=>'arial', :size=>"-1", :fg=>'bbb', :bg=>"999", :bold=>true
  end

  if Styles.dark_bg?   # If black bg
    Styles.dotted :bg=>'080808', :fg=>'111', :strike=>nil, :underline=>nil, :border=>['111', -1]
  else
    Styles.dotted :bg=>'eee', :fg=>'ddd', :strike=>nil, :underline=>nil, :border=>['ddd', -1]
  end

  notes_exclamation_color = Styles.dark_bg? ? "7c4" : "5a0"

  Styles.define :notes_exclamation,  # Green bold text
    :face=>'arial black', :size=>"0",
    :fg=>notes_exclamation_color, :bold=>true

  Styles.notes_link :fg=>(Styles.dark_bg? ? "9ce" : "08f")

  Styles.shell_prompt :fg=>'#888', :bold=>1

end

.do_as_quoteObject



988
989
990
# File 'lib/xiki/notes.rb', line 988

def self.do_as_quote
  # Make this add or remove quotes
end

.drill(file, heading = nil, *content) ⇒ Object



849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
# File 'lib/xiki/notes.rb', line 849

def self.drill file, heading=nil, *content

  prefix = Keys.prefix :clear=>true
  content = content.any? ? content.join('/') : nil

  file_orig = file.dup
  file = Bookmarks[file]

  # If bookmark wasn't found, complain
  if file =~ /^\$(\w+)/
    bm = $1
    return "| Set the following bookmark first. Then you'll be able to use this menu to\n| browse the file. The file should have '> ...' headings.\n\n@ $#{bm}\n"
  end

  # If docs/, output docs string...

  if heading == "docs"
    message = "
      > Summary
      | Convenient way for browsing the headings in this file:
      |
      - @ #{file}
      ".unindent
    return message
  end

  if ! File.exists? file
    return "
      | File doesn't exist yet, do as+update to create it:
      @ #{file}
        | > Heading
        | Stuff
      "
  end

  txt = File.open(file, 'rb') {|f| f.read}

  # If just file passed, headings...

  if ! heading

    return View.open file if prefix == "open"   # If as+open, just jump there

    txt = txt.split("\n")
    txt = txt.grep /^\>( .+)/
    return "| This file has no '>...' headings:\n@ #{file}" if txt.empty?
    return txt.join("\n")  #.gsub /^> /, '| '
  end

  # If just heading passed, show text under heading...
  heading.sub!(/^\| /, '> ')
  escaped_heading = Regexp.escape heading
  if ! content
    if prefix == :u || prefix == "open"   # If C-u on a heading, just jump there
      View.open file
      View.to_highest
      Search.forward "^#{$el.regexp_quote heading}$", :beginning=>1
      View.recenter_top
      return
    end

    txt = self.extract_block txt, heading
    ENV['no_slash'] = "1"
    return txt.gsub(/^/, '| ').gsub(/^\| $/, '|')
  end

  # If content passed

  # If C-4, grab text and save it to file / update
  if prefix == "update"
    # Update difflog

    # Grab before and after
    index = txt.index /^#{escaped_heading}$/
    index += heading.length

    before = txt[0..index]

    after = txt[index..-1].sub(/.*?^>( |$)/m, ">\\1")

    content = Tree.siblings :string=>1

    txt = "#{before}#{content}#{after}"

    DiffLog.save_diffs :patha=>file, :textb=>txt

    # return
    File.open(file, "w") { |f| f << txt }

    # Revert file if it's open?

    View.flash "- Saved!"
    return
  end

  # Navigate to heading, then content

  View.open file
  View.to_highest
  Search.forward "^#{$el.regexp_quote heading}$"
  View.recenter_top
  Search.forward "^#{$el.regexp_quote content.sub(/^\| /, '')}"
  Move.to_axis
  nil
end

.enter_juniorObject



494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/xiki/notes.rb', line 494

def self.enter_junior

  Move.to_end if Line.before_cursor =~ /^ +$/   # If at awkward position, move

  cursor = View.cursor
  line = Line.value
  indent = Line.indent line
  pipe = line =~ /^ *([|#])/ ? $1 : ""
  if Line.left == cursor || Line.right == cursor   # If beginning or end, leave current line alone
    Move.to_end
  else   # In middle of line
    Deletes.delete_whitespace
  end

  return View.<< "\n#{line[/^[ |#]*/]}  " if pipe
  View << "\n#{indent}#{pipe}  "
end

.enter_label_bulletObject



488
489
490
491
492
# File 'lib/xiki/notes.rb', line 488

def self.enter_label_bullet
  Line.to_left
  View.insert "- : "
  Move.backward 2
end

.enter_noteObject



815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
# File 'lib/xiki/notes.rb', line 815

def self.enter_note
  # If on blank line, just insert it
  indent = ""
  if ! Line.blank?
    line = Line.value
    indent, first_char = line.match(/^( *)(.)/)[1..2]

    Move.to_axis
    $el.open_line 1
  end

  Line << "#{indent}- !"
  Move.backward

  txt = Keys.input :timed=>1, :prompt=>'Enter a character: '

  expanded = Notes.expand_if_action_abbrev txt

  View << (expanded || txt)

  # If wasn't expanded prepare to edit
  ControlLock.disable if expanded == txt

  if expanded
    # Do nothing
  else
    View << "#{indent}- !"
    Move.backward
    View << txt
  end

  nil
end

.expand_if_action_abbrev(txt) ⇒ Object

If the string is “t” or “i”, or a few others, return “todo” or “imprement” etc. respectively.



984
985
986
# File 'lib/xiki/notes.rb', line 984

def self.expand_if_action_abbrev txt
  @@single_letter_abbrev[txt] || txt
end

.extract_block(txt, heading) ⇒ Object



955
956
957
958
959
# File 'lib/xiki/notes.rb', line 955

def self.extract_block txt, heading
  txt = txt.sub /.*^#{Regexp.escape heading}\n/m, ''   # Delete before block
  txt.sub! /^>( |$).*/m, ''   # Delete after block
  txt  # = txt.gsub(/^.?/, "|\\1")   # Escape with pipes
end

.from_markdown_format(txt) ⇒ Object



992
993
994
# File 'lib/xiki/notes.rb', line 992

def self.from_markdown_format txt
  txt = txt.gsub(/^#+/){"#{'>' * $&.length}"}
end

.get_block(regex = nil) ⇒ Object

Returns an instance of BlockNotes representing the block the point is currently in

def self.get_block regex="^[|>]\\( \\|$\\)"


610
611
612
613
614
615
616
617
618
# File 'lib/xiki/notes.rb', line 610

def self.get_block regex=nil
  regex ||= self.heading_regex

  regex = self.heading_regex if regex == 1
  regex = self.heading_regex(:u) if regex == 2 || regex == :u

  left, after_header, right = View.block_positions regex
  NotesBlock.new(left, after_header, right)
end

.heading_regex(prefix = nil) ⇒ Object



79
80
81
82
83
# File 'lib/xiki/notes.rb', line 79

def self.heading_regex prefix=nil
  prefix == :u ?
    "^[>=]\\{1,2\\}\\( \\|$\\)" :
    "^[>=]\\( \\|$\\)"
end

.hide_textObject



52
53
54
55
# File 'lib/xiki/notes.rb', line 52

def self.hide_text
  block = get_block
  block.hide_text
end

.initObject

Startup



449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/xiki/notes.rb', line 449

def self.init

  return if ! $el

  $el.defun(:notes_mouse_meta_click, :interactive => "e") do |e|
    $el.mouse_set_point(e)
    View.insert "hey"
  end

  $el.defun(:notes_mouse_double_click, :interactive => "e") do |e|
    next Launcher.insert "h" if Line =~ /^$/   # If blank line, launch history
    Launcher.launch_or_hide(:blink=>true)
  end

  $el.defun(:notes_mouse_toggle, :interactive => "e") do |e|
    $el.mouse_set_point(e)
    Notes.mouse_toggle
  end

  $el.defun(:notes_mode, :interactive => "", :docstring => "Apply notes styles, etc") {# |point|
    $el.el4r_lisp_eval "(setq font-lock-defaults '(nil t))"

    FileTree.apply_styles
    Notes.apply_styles
    FileTree.apply_styles_at_end
    $el.use_local_map $el.elvar.notes_mode_map
  }
  $el.el4r_lisp_eval %q<
    (progn
      (add-to-list 'auto-mode-alist '("\\\\.notes\\\\'" . notes-mode))
      (add-to-list 'auto-mode-alist '("\\\\.xik\\\\'" . notes-mode))
      (add-to-list 'auto-mode-alist '("\\\\.wik\\\\'" . notes-mode)))
    >
end

.insert_heading(options = {}) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/xiki/notes.rb', line 124

def self.insert_heading options={}
  Line.start
  orig = Line.value

  times = Keys.prefix_u? ? 1 : (Keys.prefix || 1)
  times.times { $el.insert ">" }
  View.insert " " # unless times > 1

  if options[:extra_space] || Keys.prefix_u?   # If U create blank lines.
    View.insert("\n"*4, :dont_move=>1)
    return
  end

  View.insert("\n", :dont_move=>1) if orig != ""
end

.keysObject



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/xiki/notes.rb', line 191

def self.keys

  return if ! $el

  # Get reference to map if already there (don't mess with existing buffers)
  $el.elvar.notes_mode_map = $el.make_sparse_keymap unless $el.boundp :notes_mode_map

  Keys.custom_archive(:notes_mode_map) { Notes.archive }
  Keys.custom_back(:notes_mode_map) { Notes.move_block :backwards }   # Move block up to before next block
  Keys.custom_clipboard(:notes_mode_map) { Notes.copy_block }   # block -> clipboard
  Keys.custom_delete(:notes_mode_map) { Notes.cut_block :backwards }   # block -> clear
  #     Keys.custom_expand(:notes_mode_map) { Notes.narrow_block }   # Show just block
  Keys.custom_forward(:notes_mode_map) { Notes.move_block }   # Move block down to after next block
  Keys.custom_heading(:notes_mode_map) { Notes.insert_heading }   # Insert |... etc. heading
  Keys.custom_item(:notes_mode_map) { Agenda.quick_add_line }
  # j
  Keys.custom_kill(:notes_mode_map) { Notes.cut_block }   # block -> cut
  # l
  Keys.custom_mask(:notes_mode_map) { Notes.hide_text }   # block -> hide
  Keys.custom_next(:notes_mode_map) { Notes.to_block }   # Go to block after next block
  Keys.custom_open(:notes_mode_map) { Notes.show_text }   # block -> reveal
  Keys.custom_previous(:notes_mode_map) { Notes.to_block :backwards }   # Go to block before next block
  # q
  # r
  Keys.custom_stamp(:notes_mode_map) { $el.insert Time.now.strftime("- %Y-%m-%d %I:%M%p: ").downcase.sub(' 0', ' ') }
  Keys.custom_top(:notes_mode_map) { Notes.move_block_to_top }   # block -> top
  # u
  # v
  # w
  Keys.custom_x(:notes_mode_map) { Notes.cut_block }   # block -> cut
  # y
  # z

  $el.define_key(:notes_mode_map, $el.kbd("<double-mouse-1>"), :notes_mouse_double_click)
  $el.define_key(:notes_mode_map, $el.kbd("<mouse-1>"), :notes_mouse_toggle)

  $el.define_key(:notes_mode_map, $el.kbd("<M-mouse-1>"), :notes_mouse_double_click)
  $el.define_key(:notes_mode_map, $el.kbd("<S-mouse-1>"), :notes_mouse_double_click)
  $el.define_key(:notes_mode_map, $el.kbd("<C-mouse-1>"), :notes_mouse_double_click)


  $el.define_key(:notes_mode_map, $el.kbd("C-i")) { Notes.tab_key }
end


12
13
14
15
16
17
18
# File 'lib/xiki/notes.rb', line 12

def self.menu
  %`
  - api/
    > Turn notes wiki text into html
    @ Notes.to_html "> Heading\\njust text\\n"
  `
end

.modeObject



484
485
486
# File 'lib/xiki/notes.rb', line 484

def self.mode
  $el.notes_mode
end

.mouse_toggleObject



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
# File 'lib/xiki/notes.rb', line 585

def self.mouse_toggle
  #Launcher.launch_or_hide(:blink=>true)

  # If next line is indented more, kill children
  # If starts with plus or minus, and on plus or minus, launch
  if Line.matches(/^\s*[+-]/) and View.char =~ /[+-]/
    plus_or_minus = Tree.toggle_plus_and_minus
    if ! Tree.children?
      #plus_or_minus == '+'   # If +, expand (launch

      if FileTree.dir? or ! FileTree.handles?   # If on a dir or code_tree
        Launcher.launch
      else   # If on a file in a FileTree
        FileTree.enter_lines
      end

    else   # If -, kill under
      Tree.kill_under
      Line.to_beginning
    end
  end
end

.move_block(up = false) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/xiki/notes.rb', line 85

def self.move_block up=false
  regex = self.heading_regex Keys.prefix

  times = Keys.prefix_times

  orig = Location.new

  prefix = Keys.prefix :clear=>1

  block = get_block prefix == :u ? 2 : 1
  block.delete_content

  if up
    times.times do
      Search.backward regex, :go_anyway=>true
    end
    $el.insert block.content
    Search.backward regex
  else

    move_regex = prefix == :u ? "^>" : regex

    Search.forward move_regex
    times.times do
      Search.forward move_regex, :go_anyway=>true
    end
    Move.to_axis

    View.insert block.content

    Search.backward move_regex
  end
  moved_block = get_block regex

  times == 1 ?
    moved_block.fade_in :
    orig.go
end

.move_block_to_top(no_clipboard = false) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/xiki/notes.rb', line 158

def self.move_block_to_top no_clipboard=false

  prefix_u = Keys.prefix_u :clear=>true
  block = get_block

  if prefix_u
    line = View.line_number
    scroll = View.scroll_position
    orig_right = block.right
  end

  block.fade_out unless prefix_u

  block.delete_content

  $el.beginning_of_buffer
  $el.insert block.content

  if prefix_u
    View.to_line line
    View.scroll_position = scroll
    View.cursor = orig_right
    Line.next
  else
    View.to_line 2
  end

  moved_block = get_block

  moved_block.fade_in unless prefix_u

end

.narrow_block(options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/xiki/notes.rb', line 25

def self.narrow_block options={}

  delimiter = options[:delimiter] || ">"

  # If nothing hidden, hide all but current
  if $el.point_min == 1 && ($el.buffer_size + 1 == $el.point_max)
    left, after_header, right = View.block_positions "^#{delimiter}\\( \\|$\\)"
    $el.narrow_to_region left, right
    return
  end
  # Otherwise, expand all, go to next heading, hide all but current
  $el.widen
  Notes.to_block
  left, after_header, right = View.block_positions "^#{delimiter}\\( \\|$\\)"
  $el.narrow_to_region left, right
end

.read_block(file, heading) ⇒ Object



961
962
963
# File 'lib/xiki/notes.rb', line 961

def self.read_block file, heading
  self.extract_block File.read(file), heading
end

.show_textObject



47
48
49
50
# File 'lib/xiki/notes.rb', line 47

def self.show_text
  block = get_block
  block.show_text
end

.tab_keyObject



965
966
967
968
969
# File 'lib/xiki/notes.rb', line 965

def self.tab_key
  indent = Line.indent(Line.value 0)
  Line.sub! /^ */, indent
  Line.to_beginning
end

.to_block(up = false) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/xiki/notes.rb', line 57

def self.to_block up=false

  regex = self.heading_regex Keys.prefix

  prefix = Keys.prefix :clear=>1

  times = prefix.is_a?(Fixnum) ? prefix : 1

  if up
    times.times do
      Line.to_left
      Search.backward regex
    end
  else
    times.times do
      Line.next if $el.string_match regex, Line.value   # Use elisp matcher
      Search.forward regex
      Line.to_left
    end
  end
end

.to_html(txt) ⇒ Object



620
621
622
623
624
# File 'lib/xiki/notes.rb', line 620

def self.to_html txt
  txt = txt.
    gsub(/^> (.+)/, "<h1>\\1</h1>").
    gsub(/(^|[^\n>])$/, "\\0<br>")
end