Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Ruby 1.9: many fixes. Welcome: made it appear the first time you use …

…xiki.
  • Loading branch information...
commit af04a9019d652b52c5353795df87b0e2870be625 1 parent 707bb8a
Craig Muth authored
Showing with 999 additions and 1,488 deletions.
  1. +1 −11 Gemfile
  2. +7 −3 README.markdown
  3. +110 −36 etc/command/xiki_command.rb
  4. +5 −0 etc/install/el4r_setup.sh
  5. +8 −0 etc/themes/Black_BG.notes
  6. +0 −6 etc/themes/Dark_Metal.notes
  7. +24 −0 etc/themes/Default.notes
  8. +1 −1  etc/themes/Orange_Path.notes
  9. +14 −18 etc/themes/Shiny_Blue.notes
  10. +0 −6 etc/themes/Shiny_Green.notes
  11. +5 −0 etc/themes/White_BG.notes
  12. +2 −2 etc/wrappers/wrapper.rb
  13. +1 −1  etc/www/index.rb
  14. +0 −249 etc/www/web_server.rb
  15. +5 −0 etc/xiki.org/xiki_bootstrap_source.notes
  16. +0 −709 lib/menu.rb
  17. +75 −10 lib/xiki.rb
  18. +9 −8 lib/xiki/bookmarks.rb
  19. +10 −10 lib/xiki/buffers.rb
  20. +2 −6 lib/xiki/code.rb
  21. +1 −1  lib/xiki/code_tree.rb
  22. +2 −12 lib/xiki/color.rb
  23. +6 −0 lib/xiki/console.rb
  24. +5 −1 lib/xiki/control_lock.rb
  25. +3 −1 lib/xiki/control_tab.rb
  26. +6 −2 lib/xiki/core_ext.rb
  27. +4 −5 lib/xiki/cursor.rb
  28. +3 −3 lib/xiki/diff_log.rb
  29. +4 −1 lib/xiki/effects.rb
  30. +30 −20 lib/xiki/file_tree.rb
  31. +15 −5 lib/xiki/files.rb
  32. +1 −0  lib/xiki/history.rb
  33. +7 −4 lib/xiki/key_bindings.rb
  34. +27 −31 lib/xiki/keys.rb
  35. +36 −19 lib/xiki/launcher.rb
  36. +1 −1  lib/xiki/line.rb
  37. +62 −11 lib/xiki/menu.rb
  38. +25 −34 lib/xiki/notes.rb
  39. +2 −3 lib/xiki/ol.rb
  40. +1 −1  lib/xiki/pause_means_space.rb
  41. +8 −1 lib/xiki/projects.rb
  42. +1 −1  lib/xiki/remote.rb
  43. +2 −2 lib/xiki/requirer.rb
  44. +3 −4 lib/xiki/search.rb
  45. +8 −72 lib/xiki/styles.rb
  46. +39 −31 lib/xiki/tree.rb
  47. +39 −16 lib/xiki/view.rb
  48. +6 −4 menus/address_book.rb
  49. +21 −10 menus/applescript.rb
  50. +1 −0  menus/black.menu
  51. +2 −7 menus/bootstrap.rb
  52. +8 −5 menus/browser.rb
  53. +5 −0 menus/conf.rb
  54. +30 −0 menus/dimensions_config.menu
  55. +5 −0 menus/dimensions_config.rb
  56. +33 −34 menus/docs.rb
  57. +1 −0  menus/dotsies.rb
  58. +7 −2 menus/emacs.rb
  59. +2 −2 menus/gito.rb
  60. +2 −2 menus/ip.rb
  61. +9 −2 menus/itunes.rb
  62. +3 −1 menus/javascript.rb
  63. +4 −4 menus/local_storage.rb
  64. +2 −2 menus/mongo.rb
  65. +47 −23 menus/piano.rb
  66. +57 −0 menus/r.rb
  67. +88 −26 menus/rails.rb
  68. +2 −0  menus/settings.menu
  69. +4 −1 menus/technologies.rb
  70. +18 −0 menus/welcome.menu
  71. +1 −0  menus/white.menu
  72. +21 −5 xiki.gemspec
12 Gemfile
View
@@ -1,13 +1,3 @@
source 'https://rubygems.org'
-gem 'ruby2ruby'
-gem 'ParseTree'
-gem 'httparty'
-gem 'activesupport'
-gem 'method_source'
-gem 'net-ssh'
-gem 'net-ssh'
-gem 'rspec'
-gem 'memcached'
-gem 'el4r'
-
+gemspec
10 README.markdown
View
@@ -7,21 +7,24 @@ Either install as a gem, or install from github.
## As a gem
- $ gem install xiki --pre
+ $ sudo gem install xiki --pre
## Or, from github
$ git clone git@github.com:trogdoro/xiki.git
$ cd xiki
+ $ gem install bundler
$ bundle install --system
$ cp <xiki dir>/etc/command/xiki_wrapper /usr/local/bin/xiki
$ chmod 755 /usr/local/bin/xiki
+If you don't have permission, to run some of the commands put "sudo" at the beginning of the command.
+
# Verify the 'xiki' shell command works
$ xiki
-It should delay slightly the first time, but be fast subsequent times.
+It should delay slightly the first time, but be fast subsequent times. If you run into errors and then fix them, you'll want to run the "xiki restart" command.
# Configure your editor to use Xiki
@@ -70,13 +73,14 @@ Sample configuration:
Xiki.init
KeyBindings.keys # Use default key bindings
- Themes.use "Default" # Use xiki coloring
+ Themes.use "Default" # Use xiki theme
Be sure to substitute "&lt;xiki dir&gt;" with the actual dir.
### If you get an error
If you got partially through the load...
+
- You may be able to use these keys to trouble-shoot:
- Option+e to look at the latest error in the log
- Option+l to reload xiki and .emacs
146 etc/command/xiki_command.rb
View
@@ -23,7 +23,7 @@ def self.run
argv = ARGV
if argv.empty?
- puts self.usage
+ puts "#{self.usage}\n"
@@dont_show_output = true
argv = ['start'] # So it continues on and starts server
elsif argv.length == 1 && ['status', 'stop', 'restart'].member?(argv[0])
@@ -38,8 +38,8 @@ def self.run
wasnt_running = false
begin
- `mkfifo -m 666 /tmp/xikirequest` if ! File.exists?("/tmp/xikirequest") # Always create first, so they have to be pipes and can't be files
- `mkfifo -m 666 /tmp/xikiresponse` if ! File.exists?("/tmp/xikiresponse")
+ `mkfifo -m 600 /tmp/xikirequest` if ! File.exists?("/tmp/xikirequest") # Always create first, so they have to be pipes and can't be files
+ `mkfifo -m 600 /tmp/xikiresponse` if ! File.exists?("/tmp/xikiresponse")
# Try writing to pipe...
@@ -126,45 +126,68 @@ def self.get_response
# old IO.select ["/tmp/xikiresponse"]
response = response.gets # will block if there's nothing in the pipe
-
response.strip!
response.gsub! "\036", "\n" # Escape linebreaks as 036 char (record separator)
- response = "" if @@dont_show_output
- response
+ return "" if @@dont_show_output
+ self.add_coloring response
end
end
end
def self.usage
- %`
- > Summary
- This command runs xiki menus, which come from simple files
- found in ~/menus/.
-
- > Show all menus
- % xiki all
-
- > Examples
- Call 'ip' menu
- % xiki ip
- % xiki animals
- % xiki tables
-
- > Open 'ip' menu in emacs
- % xiki -e ip
-
- > Run under current dir
- % xiki -e @git
-
- > Service
- Xiki automatically runs a service in the backgroundto keep
- things fast.
-
- % xiki # With no args, it starts the service.
- % xiki status
- % xiki stop
- % xiki restart
- `.unindent
+ txt = %`
+ > Summary
+ The 'xiki' shell command is mostly meant to be called by programs
+ that want to interface with xiki. But it is sometimes useful for
+ people to call it directly. Example usages:
+
+ $ xiki ip
+ $ xiki docs/faq
+
+ > Setting up your editor
+ The most common way to use Xiki is from a text editor. For
+ example, typing "tables" on any blank line and double-clicking on
+ it (or typing control-enter or command-enter) to browse and update
+ your mysql database.
+
+ See this file for help setting up your editor:
+
+ $xiki/README.markdown
+
+ > Service
+ The 'xiki' shell command automatically runs a service in the
+ backgroundto keep things fast.
+
+ % xiki status
+ % xiki stop
+ % xiki restart
+
+ > Interfaces
+ Xiki can be used from...
+ - A text editor
+ - The 'xiki' shell command
+ - The http://xiki/ url in your browser (experimental)
+
+ For more information type:
+
+ $ xiki docs
+
+ > Google Group
+ Join the google group for help with installing, or just to chat or
+ share your ideas:
+
+ http://groups.google.com/group/xiki/
+
+ > Troubleshooting
+ Be sure to run this command to install required gems:
+
+ % bundle install
+
+ Also see $xiki/README.markdown
+
+ `.unindent
+
+ self.add_coloring txt
end
def self.ctrl action
@@ -193,5 +216,56 @@ def self.emacs menu
nil
end
-end
+ def self.add_coloring txt
+ return txt if ! STDOUT.tty?
+ txt.gsub!(/.+/) do |line|
+ case line
+ when /^(>) (.+)/
+ "#{self.heading_bracket $1} #{self.bold $2}"
+ when /^http:\/\/.+/
+ "#{self.url $&}"
+ when /^.+\/$/
+ "#{self.path $&}"
+ when /^( *- )(.*!)$/
+ "#{self.bullet $1}#{self.exclamation $2}"
+ when /^( *)(- )(.+: )(.+)/
+ "#{$1}#{self.bullet $2}#{self.label $3}#{$4}"
+ when /^( *)(- )(.+)/
+ "#{$1}#{self.bullet $2}#{$3}"
+
+ else
+ line
+ end
+ end
+
+ txt << "\n" # Add extra linebreak, but only when in console
+ txt
+ end
+
+ def self.colorize txt, color_code
+ "\e[#{color_code}m#{txt}\e[0m"
+ end
+ def self.bullet txt
+ self.colorize txt, "1;31" # Red # colorize("1;91") # Red
+ end
+ def self.label txt
+ self.colorize txt, "1;33" # Yellow
+ end
+ def self.path txt
+ colorize(txt, "1;90")
+ end
+ def self.url txt
+ colorize(txt, "1;36") # Cyan
+ end
+ def self.heading_bracket txt
+ colorize(txt, "0;37")
+ end
+ def self.bold txt
+ colorize(txt, "1")
+ end
+ def self.exclamation txt
+ colorize(txt, "1;32") # Green
+ end
+
+end
5 etc/install/el4r_setup.sh
View
@@ -0,0 +1,5 @@
+cd `dirname \`gem contents trogdoro-el4r | grep setup.rb\``
+ruby setup.rb
+cd bin/
+ruby -S el4r-rctool -p
+ruby -S el4r-rctool -i
8 etc/themes/Black_BG.notes
View
@@ -0,0 +1,8 @@
+$el.set_face_background :trailing_whitespace, "#333333"
+
+Styles.define :default, :bg=>'151515', :fg=>'fff'
+Styles.define :fringe, :bg=>'151515', :fg=>'111111'
+
+Styles.minibuffer_prompt :size=>110, :face=>"Monaco", :fg=>"#bbb"
+Styles.minibuffer :size=>110, :face=>"Monaco"
+Styles.echo_area :size=>110, :face=>"Monaco"
6 etc/themes/Dark_Metal.notes
View
@@ -14,12 +14,6 @@ Styles.mode_line_inactive(
:bold=>false,
:fg=>'000'
)
-Styles.mode_line_dir(
- :fg=>"777",
- :size=>"0",
- :face=>"arial",
- :bold=>false
- )
Styles.mode_line_file(
:fg=>"fff",
:size=>"0",
24 etc/themes/Default.notes
View
@@ -0,0 +1,24 @@
+Themes.use "Black BG"
+Themes.use "Shiny Blue"
+Themes.use "Path Mode Line"
+
+$el.el4r_lisp_eval %`
+ (progn
+ (tool-bar-mode -1) ; Turn off the toolbar
+
+ (custom-set-variables
+ '(tabbar-mode nil) ; No tabs
+ '(cua-rectangle-mark-key (kbd "<C-S-return>")) ; No tabs
+ ;; '(tabbar-mode t) ; No tabs
+ ;; '(show-paren-mode nil)
+ )
+
+ (set-face-attribute 'region nil :background "#333333" :foreground "#ffffff") ;; More mac-like selection color
+
+ (setq-default
+ frame-title-format
+ '("%b"))
+
+ (setq frame-title-format '("%b" ))
+ )
+ `
2  etc/themes/Orange_Path.notes
View
@@ -1,4 +1,4 @@
-if Styles.inverse # Black bg
+if Styles.dark_bg? # Black bg
Styles.mode_line :bg=>'333', :border=>['666', -1], :face=>'Lucida Grande', :size=>'3', :bold=>false, :fg=>'fff'
Styles.mode_line_inactive :bg=>'666', :border=>['888', -1], :face=>'Lucida Grande', :size=>'3', :bold=>false, :fg=>'fff'
32 etc/themes/Shiny_Blue.notes
View
@@ -1,27 +1,23 @@
Styles.mode_line(
- :bg=>'5483bf',
- :border=>['6593b3', -5, 'released-button'],
- :face=>'Lucida Grande',
- :size=>'3',
- :bold=>false,
- :fg=>'fff'
+ :bg=>'6483af',
+ :border=>['6483af', 3],
+ :face=>"arial",
+ :bold=>true,
+ :size=>'1',
+ :fg=>'001122'
)
+
Styles.mode_line_inactive(
- :bg=>'bbb',
- :border=>['bbbbbb', -1],
- :face=>'Lucida Grande',
- :bold=>false,
- :fg=>'000'
- )
-Styles.mode_line_dir(
- :fg=>"222222",
- :size=>"0",
+ :bg=>'bbbbbb',
+ :border=>['bbbbbb', 3],
:face=>"arial",
- :bold=>false
+ :bold=>true,
+ :size=>'1',
+ :fg=>'555555'
)
+
Styles.mode_line_file(
:fg=>"fff",
- :size=>"0",
:face=>"arial",
- :bold=>false
+ :bold=>true
)
6 etc/themes/Shiny_Green.notes
View
@@ -13,12 +13,6 @@ Styles.mode_line_inactive(
:bold=>false,
:fg=>'000'
)
-Styles.mode_line_dir(
- :fg=>"222222",
- :size=>"0",
- :face=>"arial",
- :bold=>false
- )
Styles.mode_line_file(
:fg=>"fff",
:size=>"0",
5 etc/themes/White_BG.notes
View
@@ -0,0 +1,5 @@
+$el.set_face_background :trailing_whitespace, "#aaaaaa"
+
+Styles.define :default, :bg=>'f8f8f8', :fg=>'000'
+Styles.define :fringe, :bg=>'f8f8f8', :fg=>'f8f8f8'
+
4 etc/wrappers/wrapper.rb
View
@@ -1,8 +1,8 @@
# Gets shelled out to by xiki to delegate call to a no-dependency .rb file.
# Just gets the args passed in and requires and invokes.
-# TODO Don't hard-code path
-require "/projects/xiki/lib/ol.rb"
+# TODO Don't hard-code path - use __FILE__?
+# require "/projects/xiki/lib/xiki/ol.rb"
file = ARGV.shift
path = ARGV.shift
2  etc/www/index.rb
View
@@ -2,7 +2,7 @@
print "Content-type: text/html\n\n";
-require "/projects/xiki/lib/ol.rb"
+require "../../lib/xiki/ol.rb"
require "web_server"
require "cgi"
WebServer.index
249 etc/www/web_server.rb
View
@@ -1,246 +1,5 @@
class WebServer
- def self.htmlify txt, options={}
-
- return txt if ENV['HTTP_ACCEPT'] !~ /\Atext\/html/ # Only process if request wants html
-
- # If starts with <foo or @bootstrap, just render it as html or bootstrap...
-
- if txt =~ /\A<\w/
- return txt
- elsif txt =~ /\A@bootstrap\/\n /
-
- xiki_dir = File.expand_path "#{File.dirname(__FILE__)}/../.."
-
- $:.unshift "#{xiki_dir}/lib"
- ["xiki/ol", "xiki/core_ext", "xiki/line", "xiki/tree", "../../menus/bootstrap"].each{|o| require o}
-
- txt.slice! /.+\n/
- txt = txt.unindent
-
- txt = Bootstrap.process txt
-
- return txt
- end
-
- # Turn menu text into html...
-
- # TODO: should probably maintain indenting?
- txt.gsub! /^ *\| ?/, ''
-
- txt.gsub! /^( *)[+-]+ /, "\\1" # Get rid of bullets
- txt.gsub! /> (.+)/, "<h1>\\1</h1>"
-
- path = ENV['REQUEST_URI']# =~ /\/$/ ? "" : "#{ENV['REQUEST_URI']}/" # Use relative links if path ends in slash, otherwise use absolute
- path = "#{path}/" if path !~ /\/$/
-
- txt.gsub!(/^( *)(.+?)(\/?)$/){
- all = $&
- indent, item, slash = $1, $2, $3
- next all if all =~ /<h/ || all !~ /\/$/
- my_path = path
- my_path = "/" if item.slice!(/^<< /)
- my_path = "/" if item.slice!(/^@ ?/)
- "#{indent}<a href=\"#{my_path}#{item}\">#{item.gsub '_', ' '}</a>"
- } # no slash
-
- txt.gsub!(/^ +/){"&nbsp; " * $&.length} # Get rid of bullets
-
- txt.gsub!(/.+/){
- all = $&
- next all if all =~ /<h/
- next "<p class='info'>#{all}</p>" if all !~ /^<a/ # Don't end in "/" - just informational
- all
- }
- txt.gsub! /^$/, "<p class='blank'>&nbsp;</p>"
-
- print %`
- <style>
- a {
- text-decoration: none;
- }
-
- .content a.selected {
- background: -moz-linear-gradient(center top, #58b, #7ad) repeat scroll 0 0 transparent;
- }
- .content a {
- color: #666;
- display: block;
-
- border-radius: 2px;
- border: solid 1px;
- border-color: #eee #ddd #bbb #ddd;
- background: -moz-linear-gradient(center top, #fff, #f1f1f1) repeat scroll 0 0 transparent;
- background: -webkit-gradient(linear,center bottom,center top,from(#f1f1f1),to(#fff));
- display: block;
- padding: 10px 16px;
- text-shadow: 0 1px 0 #fff;
- font-weight: bold;
- }
- a:hover {
- background: -moz-linear-gradient(center top, #f8f8f8, #e1e1e1) repeat scroll 0 0 transparent;
- background: -webkit-gradient(linear,center bottom,center top,from(#e1e1e1),to(#f8f8f8));
- }
- body {
- font-family: arial;
- margin: 50px;
- font-size: 15px;
- color: #666;
- line-height: 21px;
- background-color: #f8f8f8;
- }
- p {
- margin: 0;
- }
- .blank {
- line-height: 12px;
- }
- /* Or type some css here (to run in the browser) */
- h1 {
- color: #000;
- font-family: arial;
- font-size: 16px;
- font-weight: bold;
- margin: 11px 0 7px;
- }
- .save {
- margin: 0 20px 10px 20px;
- font-size: 15px;
- }
- form {
- margin: 0;
- }
- textarea {
- border: solid #ccc 1px;
- margin: 2px 20px 13px 20px;
- padding: 7px;
- width: 80%;
- font-size: 15px;
- color: #555;
- height: 150px;
- line-height: 20px;
- }
- .toggle {
- font-size: 13px;
- margin: 15px 20px 0px 20px;
- font-weight: bold;
- }
- .toggle a {
- color: #aaa;
- }
- .info {
- margin: 0 0 6px;
- }
- pre {
- font-weight: bold;
- }
-
- </style>
- `
-
- puts %`<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>`
-
- if ! options[:no_keys]
- print %`
- <script>
- filter_pattern = "";
- started_searching = false;
- $(function(){
-
- $(window).focus(function () {
- filter_pattern = "";
-
- $('body').css("opacity", 1.0);
- $('p, h1, a').show();
- $('a').removeClass("selected");
- });
-
- $('body').keypress(function(e){
- if(e.ctrlKey || e.altKey || e.metaKey) return;
- var char = e.which;
- var letter = String.fromCharCode(char).toLowerCase();
- //console.log(char)
- if(char == 13){
- $("a:visible:eq(0)").click();
- e.stopPropagation();
- return false;
- }
-
- if(letter == " "){
- if(started_searching) filter_pattern = "";
- else window.location = "/";
- e.stopPropagation();
- return false;
- }
-
- if(! letter.match(/[0-9a-z]/)) return true;
-
- started_searching = true;
- filter_pattern += letter;
-
- //console.log(filter_pattern);
-
- // If more than 100, don't use fade
- var count = $('p, h1, a').filter(':visible').length;
- var fade = count < 50;
-
- $('p, h1, a').each(function(i, e){
- e = $(e);
- if(e.is(":hidden")) return;
- var html = e.html().replace(/<.+?>/g, '');
- //console.log(html);
- if(html.toLowerCase().indexOf(filter_pattern) == -1)
- fade ? e.slideUp(400) : e.hide();
- // Get content
- // Remove tags
- // Hide if remaining doesn't match regex (/on/)
- })
-
- });
-
- $('a').click(function(e){
- var target = $(e.target);
- target.toggleClass("selected");
-
- $('body').animate({opacity: 0.0}, {easing: 'swing', duration: 150});
- window.setTimeout(function(){ window.location = target.attr('href'); }, 150);
- return false;
- });
-
- })
- </script>
- `
- end
-
- "<div class='content'>#{txt}</div>"
- end
-
-
- def self.usage
- txt = "
- > Summary
- This url displays xiki menus, which come from simple files found in ~/menus/.
-
- > Show all menus
- all/
-
- > Examples
- ip/
- animals/
- sharks/
- tables/
-
- > Create menu
- Just go to the url of a menu that doesn't exist yet:
- unicorn/
-
- > Docs
- docs/
- ".sub("\n", '').gsub(/^ /, '')
-
- print WebServer.htmlify txt
-
- end
def self.index
no_keys = false
@@ -267,16 +26,8 @@ def self.index
txt = `#{command}`
- # rescue e=>Exception
- # puts "<pre>#{e.message}\n#{e.backtrace}</pre>"
- # Ol << "e: #{e.message}"
- # Ol << "e: #{e.backtrace}"
- # Ol << "If we get the permission problem, provide .notes file that will run command to run xiki command once (message explaining it first)!"
- # end
-
# TODO: return different string when the service is down
- # Ol << "Extract to new method: suggest_creating!!"
if txt.empty?
menu = menu.sub /\/$/, ''
5 etc/xiki.org/xiki_bootstrap_source.notes
View
@@ -1,8 +1,10 @@
> Deploy
- /tmp/
$ scp tmp.html xiki@xiki.org:/var/www/xiki.org/index.html
+ % scp tmp.html xiki@xiki.org:/var/www/xiki.org/screencasts/index.shtml
http://xiki.org
+http://xiki.org/screencasts
> Home page
@@ -160,6 +162,9 @@ bootstrap/
- h1/Screencasts
<div class="section">
+ <object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/bUR_eUVcABg&hl=en_US&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/bUR_eUVcABg&hl=en_US&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object>
+
+ <div class="section">
<object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/LA-lViZ8vls&hl=en_US&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/LA-lViZ8vls&hl=en_US&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object>
<div class="section">
709 lib/menu.rb
View
@@ -1,709 +0,0 @@
-class Menu
-
- def self.menu
- '
- - history/
- - @log/
- - @last/
- - @all/
- - .create/
- - here/
- - class/
- - .install/
- - gem/
- - .setup/
- - @~/menus/
- - .reload_menus/
- - .api/
- > Summary
- | How to use ruby code to define menus.
- |
- | You can create sophisticated menus backed by classes, or by using other
- | simple means:
- - .classes/
- - .simple class/
- - .menu with method/
- - .menu with two methods/
- - other/
- - With a string/
- |
- | Menu.fish :menu=>"- salmon/\n- tuna/\n - yellow fin/"
- |
- Try it out by typing 1 do_ruby (C-1 Ctrl-d Ctrl-r) while on it, then
- double-clicking on this menu to see what happens:
- |
- @fish/
- |
- - Delegating to an existing menu/
- |
- | Menu.critters :menu=>"foo/animals"
- |
- @critters/
- |
- - Using a block/
- |
- | Menu.foo do
- | "hey/"
- | end
- |
- The block can optionally take a |path| param to handle multiple levels
- of nesting.
- |
- | Menu.foo do |path|
- | "hey/#{path}"
- | end
- |
- - Extract menu text from somewhere/
- | Tree.children just expects text that is in the form of a menu (lines with
- | 2-space indenting for nesting). So, the text can be pulled from
- | anywhere, such as a part of a larger file:
- |
- | Menu.lawn do |path|
- | menu = Notes.read_block("/tmp/garage.notes", "> Lawn")
- | Tree.children menu, Tree.rootless(path)
- | end
- |
- |
- | If you want to create a very simple menu you can do so without code,
- | by just putting the menu in a file such as ~/menu/foo.menu. See:
- |
- << docs/how_to_create/
- - .docs/
- - .How to use/
- - .How to create/
- - .keys/
- > Summary
- | Helpful keyboard shortcuts when using menus.
- |
- | - as+menu
- | - Save changes to menu (or create new one)
- | - to+menu
- | - Jump to file that implements menu
- |
- '
- end
-
- def self.install *args
- Xiki.dont_search
- Tree.quote "
- > TODO
- - implement this.
-
- - Should it look for installed gems with this name?
- - Should it just show commands to do a gem install?
- - How would it know whether it the gem has a xiki menu?
- "
- end
-
- def self.create *args
- type = args[0]
-
- return self.create_here if type == "here"
- return self.create_class if type == "class"
- return self.create_more(*args.drop(1)) if type == "more"
-
- "- unknown option #{type} passed to .create!"
- end
-
- def self.create_here
-
- # TODO: Handle various use cases
- # "menu/create/here/" at left margin
- # "@menu/create/here/" nested
- # "menu/create/\n here/" at left margin
- # "@menu/create/\n here/" nested
-
- trunk = Xiki.trunk
- if wrapper = trunk[-2] # If @menu/create/here is nested
- menu = Tree.root wrapper
- else # If put it under a fake menu
-
- # What? This is if it's not nested? - is this used?
-
- # TODO: Go to left margin and remove menu...
-
- Tree.to_root
-
- Tree.kill_under
- menu = "foo"
- Line.sub! /([ +-]*).*/, "\\1#{menu}/"
- # Insert it wherever we are
- end
- Xiki.dont_search
-
- name_text = menu == "foo" ?
- "and change '#{menu}' to something" :
- "to go under the '#{menu}' menu"
-
- snake = TextUtil.snake_case menu
-
- Tree << "
- | Supply a few items here. Then do as+menu (type Ctrl-a Ctrl-m) to create
- | the '#{menu}' menu. Or, just create '~/menus/#{snake}.menu' yourself.
- - example item/
- - another/
- - and another/
- "
-
- nil
-
- end
-
- def self.create_class
- trunk = Xiki.trunk
- if wrapper = trunk[-2]
- # Just do in-line
- menu = TextUtil.snake_case Tree.root(wrapper)
- else
- menu = 'foo'
- end
-
- Xiki.dont_search
-
- Tree << %`
- | Update this sample class to your liking. Then do as+update (type
- | Ctrl-a, Ctrl-u) to create the '#{menu}' class file.
- - @~/menus/
- - #{menu}.rb
- | class #{TextUtil.camel_case(menu)}
- | def self.menu *args
- | "- Args Passed: \#{args.inspect}\\n- Customize me in) @ ~/menus/#{menu}.rb"
- | end
- | end
- - more examples) @menu/api/classes/
- `
- nil
- end
-
- def self.simple_class *args
- root = 'foo'
- trunk = Xiki.trunk
- root = TextUtil.snake_case(trunk[-2][/^[\w -]+/]) if trunk.length > 1 # If nested path (due to @), grab root of parent
-
- %`
- - @~/menus/
- - #{root}.rb
- | class #{TextUtil.camel_case(root)}
- | def self.menu *args
- | "- args passed: \#{args.inspect}\n- Customize me in) @ ~/menus/#{menu}.rb"
- | end
- | end
- `
- end
-
- def self.menu_with_method *args
- root = 'foo'
- trunk = Xiki.trunk
- root = TextUtil.snake_case(trunk[-2][/^[\w -]+/]) if trunk.length > 1 # If nested path (due to @), grab root of parent
-
- %`
- - @~/menus/
- - #{root}.rb
- | class #{TextUtil.camel_case(root)}
- | def self.menu
- | "
- | - cake/
- | - chocolate/
- | - .pie/
- | "
- | end
- |
- | def self.pie
- | "- apple/"
- | end
- | end
- `
- end
-
- def self.menu_with_two_methods *args
- root = 'foo'
- trunk = Xiki.trunk
- root = TextUtil.snake_case(trunk[-2][/^[\w -]+/]) if trunk.length > 1 # If nested path (due to @), grab root of parent
-
- %`
- - @~/menus/
- - #{root}.rb
- | class #{TextUtil.camel_case(root)}
- | def self.menu
- | "
- | - sammiches/
- | - ham/
- | - .buy/
- | - tofu/
- | - .buy/
- | - .checkout/
- | - cash/
- | - credit/
- | "
- | end
- | def self.buy category, item
- | "- buying \#{item} \#{category}"
- | end
- | def self.checkout kind
- | "- checking out as \#{kind}..."
- | end
- | end
- |
- `
- end
-
- def self.how_to_use *args
- %`
- > Summary
- | How to use Xiki menus. Note this refers to the wiki-style menus, not the menu bar.
- |
- | All menus can be used the same way. Just type something and double-click
- | on it (or type Ctrl-enter while the cursor is on the line).
- |
- - example/
- | 1: type "foo" on a line (the "@" isn't necessary when the line isn't indented)
- @ foo
- |
- | 2: double-click on it to drill in. You can try it on the line above. It will look like this:
- @ foo/
- | - sammiches/
- | - dranks/
- |
- | 3: double-click to drill in further. It will look like this:
- @ foo/
- | - sammiches/
- | - ham/
- | - tofu/
- | - dranks/
- |
- - using the mouse/
- | You can click on the "bullets" (the - and + at the beginnings of lines)
- | to expand and collapse. You can also double-click to expand and
- | collapse.
- |
- - search to narrow down/
- | When you double-click a line the cursor turns blue and you can type
- | letters to search and narrow down the list.
- |
- - misc keys/
- | - Return: stops searching and launches (expands file or dir)
- | - Tab: like return but hides others
- | - ;: like return but collapses path
- |
- | - C-g: stops searching
- |
- | - Arrow keys: you can use them to go up and down and expand and collapse
- |
- `
- end
-
- def self.how_to_create *args
- txt = %q`
- > Summary
- | How to make your own menus in Xiki. Note this refers to wiki-style
- | menus (such as this one), not the menu bar.
- |
- - Creating .menu files/
- | You can make menus without code, by just put "whatever.menu" files in the
- | "menu/" dir in your home dir.
- |
- | For example you could create a "foo.menu" file with the contents
- | "- sammiches/..." etc:
- |
- - TODO: get these to expand out somehow! - maybe pass another arg to Tree.children below? - probably bad idea
- - ~/menus/
- - foo.menu
- | - sammiches/
- | - ham/
- | - tofu/
- | - dranks/
- | - foty/
- |
- - Delegating/
- | This makes a foo/ menu that you can expand. Even though these menus
- | don't run code themselves, they can delegate to other menus or run code,
- | like:
- |
- - ~/menus/
- - foo.menu
- | - @mymenu/
- | - @MyClass.my_method
- |
- `
-
- Tree.children(txt, args.join('/'))
- end
-
- def self.reload_menus
- Launcher.reload_menu_dirs
- View.flash
- nil
- end
-
- def self.[] path
- path, rest = path.split '/', 2
-
- self.call path, rest
- end
-
- def self.call root, rest=nil
- root = root.gsub /[- +]/, '_'
- menus = Launcher.menus
- block = menus[0][root] || menus[1][root]
- return if block.nil?
- Tree.output_and_search block, :line=>"#{root}/#{rest}", :just_return=>1
- end
-
- def self.method_missing *args, &block
- Launcher.method_missing *args, &block
- "- defined!"
- end
-
- def self.split path, options={}
- path = path.sub /\/$/, ''
- path = Tree.rootless path if options[:rootless]
-
- return [] if path.empty?
-
- groups = path.split '/|', -1
-
- result = groups[0] =~ /^\|/ ?
- [groups[0]] :
- groups[0].split('/', -1)
-
- result += groups[1..-1].map{|o| "|#{o}"}
- end
-
- def self.to_menu
- # Take best guess, by looking through dirs for root
- trunk = Xiki.trunk
-
- return View.<<("- You weren't on a menu\n | To jump to a menu's implementation, put your cursor on it\n | (or type it on a blank line) and then do as+menu (ctrl-a ctrl-m)\n | Or, look in one of these dirs:\n - ~/menus/\n - $xiki/menus/") if trunk[-1].blank?
-
- root = trunk[0][/^[\w _-]+/]
-
- root = trunk[-1][/^[\w _-]+/] if ! Keys.prefix_u
-
- root.gsub!(/[ -]/, '_') if root
-
- root.downcase!
-
- (["#{Xiki.dir}lib/"]+Launcher::MENU_DIRS).reverse.each do |dir|
- next unless File.directory? dir
- file = Dir["#{dir}/#{root}.*"]
- next unless file.any?
- return View.open file[0]
- end
-
- # message = "
- # - No menu found:
- # | No \"#{root}\" menu or class file found in these dirs:
- # @ ~/menus/
- # @ $x/menus/
- # ".unindent
-
- # Should be able to get it right from proc
-
- proc = Launcher.menus[1][root]
-
- return View.flash "- Menu 'root' doesn't exist!", :times=>4 if ! proc
-
- location = proc.source_location # ["./firefox.rb", 739]
- location[0].sub! /^\.\//, Xiki.dir
- View.open location[0]
- View.line = location[1]
-
- end
-
- def self.external menu, options={}
-
- View.message ""
-
- View.wrap :off
-
- # IF nothing passed, must want to do tiny search box
- if menu.empty?
- Launcher.open ""
- View.message ""
- View.prompt "Type anything", :timed=>1, :times=>2 #, :color=>:rainbow
-
- Launcher.launch
- else
- Launcher.open menu, options
- end
- end
-
- def self.as_menu
- orig = View.cursor
-
- Tree.to_root
-
- root, left = Line.value, View.cursor
- root = Line.without_label :line=>root
-
- root = TextUtil.snake_case(root).sub(/^_+/, '')
-
- if Line.value(2) =~ /^ +\| Supply a few items here/ # If sample text, remove
- Line.next
- while Line.=~(/^ +\| /)
- Line.delete
- end
- Line.previous
- orig = nil
- end
-
- Tree.after_children
- right = View.cursor
- View.cursor = left
-
- # Go until end of paragraph (simple for now)
- Effects.blink :left=>left, :right=>right
- txt = View.txt left, right
- txt.sub! /.+\n/, ''
- txt.gsub! /^ /, ''
- txt.unindent
-
- return Tree << "| You must supply something to put under the '#{root}' menu.\n| First, add some lines here, such as these:\n- line/\n- another line/\n" if txt.empty?
-
- path = File.expand_path "~/menus/#{root}.menu"
-
- file_existed = File.exists? path
-
- if file_existed
- treeb = File.read path
- txt = Tree.restore txt, treeb
-
- DiffLog.save_diffs :patha=>path, :textb=>txt
- end
-
- File.open(path, "w") { |f| f << txt }
-
- View.cursor = orig if orig
-
- require_menu path
-
- View.flash "- #{file_existed ? 'Updated' : 'Created'} ~/menus/#{root}.menu", :times=>3
- nil
- end
-
- @@loaded_already = {}
-
- def self.load_if_changed file
- return :not_found if ! File.exists?(file)
- previous = @@loaded_already[file]
- recent = File.mtime(file)
-
- if previous == nil
- # require file
- load file
- @@loaded_already[file] = recent
- return
- end
-
- return if recent <= previous
-
- load file
- @@loaded_already[file] = recent
- end
-
- def self.collapser_launcher
-
- line = Line.value
- arrows = line[/<+/].length
- arrows -= 1 if arrows > 1 # Make "<<" go back just 1, etc.
-
- # line.sub! /(^ +)= /, "\\1< " # Temporarily get "=" to work too
- line = Line.without_label :line=>line
-
- skip = line.empty? && arrows - 1
-
- Line.sub! /^( +)<+ .+/, "\\1- " # Delete after bullet to prepare for loop
-
- arrows.times do |i|
-
- # If no items left on current line, jump to parent and delete
- if Line =~ /^[ +-]+$/
- Tree.to_parent
- Tree.kill_under
- Move.to_end
- end
-
- unless i == skip # Remove last item, or after bullet if no items
- Line.sub!(/\/[^\/]+\/$/, '/') || Line.sub!(/^([ @+-]*).*/, "\\1")
- end
- end
-
- if Line.indent.blank?
- line.sub! /^@ ?/, ''
- Line.sub! /^@ ?/, ''
- end
-
- Line << line unless skip
- Launcher.launch
-
- end
-
- def self.root_collapser_launcher
-
- View.cursor
-
-
- # Grab line
- line = Line.value
-
- arrows = line[/<+/].length
-
- line.sub!(/ *<+@ /, '')
-
- # Go up to root, and kill under
- arrows.times { Tree.to_root }
- Tree.kill_under
-
- # Insert line, and launch
- old = Line.delete :leave_linebreak
- old.sub! /^( *).+/, "\\1"
- old << "@" if old =~ /^ / # If any indent, @ is needed
- View << "#{old}#{line}"
-
- Launcher.launch
- end
-
- def self.replacer_launcher
- Line.sub! /^( +)<+= /, "\\1+ "
-
- # Run in place, grab output, then move higher and show output
-
- orig = View.line
- Launcher.launch :no_search=>1
-
- # If didn't move line, assume it had no output, and it's collapse things itself
- return if orig == View.line
-
- # If it inserted something
-
- output = Tree.siblings :everything=>1
-
- # return
-
- # Shouldn't this be looping like self.collapser_launcher ?
- Tree.to_parent
- Tree.to_parent
- Tree.kill_under :no_plus=>1
- Tree << output
-
- # TODO: do search now, after insterted?
-
- end
-
- def self.menu_to_hash txt
- txt = File.read txt if txt =~ /\A\/.+\z/ # If 1 line and starts with slash, read file
-
- txt.gsub(/^\| /, '').split("\n").inject({}) do |o, txt|
- txt = txt.split(/ : /)
- o[txt[0]] = txt[1]
- o
- end
-
- end
-
- # def self.config txt, *args
-
- # # TODO: implement
- # # Args look like sample invocation below
- # # If not there, create it first, using supplied default
- # # Insert quoted file contents to be edited
-
- # # Sample invocation
- # # Menu.config "
- # # - @ ~/xiki_config/browser.notes
- # # | - default browser:
- # # | - Firefox
- # # | - others:
- # # | - Safari
- # # | - Chrome
- # # ", *args
-
- # "TODO"
- # end
-
- # Moves item to root of tree (replacing tree), then launches.
- def self.do_as_menu
- line = Line.value
-
- # If on ^@... line and there's child on next line...
-
- on_subtree = line =~ /^[ +-]*@/ && Tree.has_child?
-
- txt = on_subtree ? Tree.subtree.unindent.sub(/^[ @+-]+/, '') : Tree.path.last
-
- Keys.prefix_u ? Tree.to_root(:highest=>1) : Tree.to_root
- Tree.kill_under
-
- Line.sub! /^([ @]*).+/, "\\1#{txt}"
-
- return if on_subtree
-
- # replace line with menu
-
- Launcher.launch
- end
-
-
- # The following 3 methods are for the menu bar
- # - a different use of the "Menu" class
- # TODO move them into menu_bar.rb ?
-
- def self.add_menu *name
- menu_spaces = name.join(' ').downcase
- menu_dashes = name.join('-').downcase
- name = name[-1]
-
- lisp = %Q<
- (define-key global-map
- [menu-bar #{menu_spaces}]
- (cons "#{name}" (make-sparse-keymap "#{menu_dashes}")))
- >
- $el.el4r_lisp_eval lisp
-
- menu = $el.elvar.menu_bar_final_items.to_a
- $el.elvar.menu_bar_final_items = menu.push(name.downcase.to_sym)
- end
-
- def self.add_item menu, name, function
-
- menu_spaces = menu.join(' ').downcase
- lisp = "
- (define-key global-map
- [menu-bar #{menu_spaces} #{function}]
- '(\"#{name}\" . #{function}))
- "
- $el.el4r_lisp_eval lisp
- end
-
- ROOT_MENU = 'Keys'
-
- def self.init
-
- return if ! $el
-
- Mode.define(:menu, ".menu") do
- Notes.mode
- end
-
- add_menu ROOT_MENU
-
- menus = [
- [ROOT_MENU, 'To'],
- [ROOT_MENU, 'Open'],
- [ROOT_MENU, 'Layout'],
- [ROOT_MENU, 'As'],
- [ROOT_MENU, 'Enter'],
- [ROOT_MENU, 'Do'],
- [ROOT_MENU, 'Search']
- ]
- menus.reverse.each do |tuple|
- add_menu tuple[0], tuple[1]
- end
- end
-
-
-end
-
-Menu.init # Define mode
-
-
85 lib/xiki.rb
View
@@ -10,13 +10,13 @@ class Xiki
def self.dir
@@dir
end
-
end
$el.el4r_lisp_eval '(ignore-errors (kill-buffer "Issues Loading Xiki"))' if $el
+$el.set_process_query_on_exit_flag($el.get_buffer_process("*el4r:process*"), nil) if $el
-# $LOAD_PATH << "#{xiki_dir}/lib"
+# $LOAD_PATH << "#{xiki_dir}/lib"
# Require some of the core files
require 'rubygems'
require 'xiki/trouble_shooting'
@@ -30,6 +30,9 @@ def self.dir
# Launcher.add_class_launchers classes
class Xiki
+
+ $el.elvar.xiki_loaded_once = nil if $el && ! $el.boundp(:xiki_loaded_once)
+
def self.menu
%`
- .tests/
@@ -76,6 +79,18 @@ def self.menu
- stop/
- restart/
- log/
+ - el4r/
+ > Configure
+ @#{Xiki.dir}
+ % sudo bash etc/install/el4r_setup.sh
+
+ - docs/
+ | This will create/update files in your home directory, which make el4r
+ | point to the version of ruby currently active.
+ |
+ | You can run this multiple times.
+ - .misc/
+ - .dont show welcome/
- api/
> Summary
Here are some functions that will always be available to menu classes,
@@ -95,7 +110,7 @@ def self.menu
def self.install_icon arg
- emacs_dir = "/Applications/Emacs.app"
+ emacs_dir = "/Applications/Aquamacs Emacs.app"
return "- Couldn't find #{emacs_dir}!" if ! File.exists?("#{emacs_dir}")
@@ -115,12 +130,42 @@ def self.install_icon arg
# if change was already made, say so
# TODO
- # icon
- # copy over
- # cp "#{Xiki.dir}etc/shark.icns"
-
- "- finish implementing!"
+ # 1. Copy icon into app
+ # cp "#{Xiki.dir}etc/shark.icns" "/Applications/Aquamacs Emacs.app/Contents/Resources/"
+ # - /Applications/Aquamacs Emacs.app/
+ # - Contents/Resources/
+ # + shark.icns
+ # + emacs-document.icns
+
+ # 2. Update Info.plist
+ # /Applications/Aquamacs Emacs.app/Contents/
+ # - Info.plist
+ # |+ <dict>
+ # |+ <key>CFBundleTypeExtensions</key>
+ # |+ <array>
+ # |+ <string>notes</string>
+ # |+ <string>menu</string>
+ # |+ <string>xiki</string>
+ # |+ </array>
+ # |+ <key>CFBundleTypeIconFile</key>
+ # |+ <string>shark.icns</string>
+ # |+ <key>CFBundleTypeName</key>
+ # |+ <string>Xiki File</string>
+ # |+ <key>CFBundleTypeOSTypes</key>
+ # |+ <array>
+ # |+ <string>TEXT</string>
+ # |+ <string>utxt</string>
+ # |+ </array>
+ # |+ <key>CFBundleTypeRole</key>
+ # |+ <string>Editor</string>
+ # |+ </dict>
+
+ # 3. Tell user to drag the .app icon out of the "Applications" folder and back in
+ # - Or google to find a command that will do the same thing
+
+
+ "- TODO: finish implementing!"
end
def self.insert_menu
@@ -344,10 +389,13 @@ def self.on_open
end
def self.init
+
# Get rest of files to require
- classes = Dir["lib/xiki/*.rb"]
+ classes = Dir["./lib/xiki/*.rb"]
+
classes = classes.select{|i|
+ i !~ /\/ol.rb$/ && # Don't load Ol twice
i !~ /\/xiki.rb$/ && # Remove self
i !~ /\/key_bindings.rb$/ && # Remove key_bindings
i !~ /__/ # Remove __....rb files
@@ -368,7 +416,7 @@ def self.init
Requirer.require_classes classes
# key_bindings has many dependencies, require it last
- Requirer.require_classes ['lib/xiki/key_bindings.rb']
+ Requirer.require_classes ['./lib/xiki/key_bindings.rb']
Launcher.add_class_launchers classes.map{|o| o[/.*\/(.+)/, 1]}
Launcher.reload_menu_dirs
@@ -380,6 +428,16 @@ def self.init
Mode.define(:xiki, ".xiki") do
Xiki.on_open
end
+
+ if $el
+ # If the first time we've loaded
+ if ! $el.elvar.xiki_loaded_once && ! Menu.line_exists?("misc config", /^- dont show welcome$/) && ! View.buffer_visible?("Issues Loading Xiki")
+ Launcher.open("welcome/", :no_search=>1)
+ end
+
+ $el.elvar.xiki_loaded_once = true
+ end
+
end
def self.process action
@@ -403,4 +461,11 @@ def self.process action
end
end
+ def self.dont_show_welcome
+ Menu.append_line "misc config", "- dont show welcome"
+ end
+
+ def self.finished_loading?
+ @@finished_loading
+ end
end
17 lib/xiki/bookmarks.rb
View
@@ -61,9 +61,9 @@ def self.save arg=nil
# If arg is a symbol, use it as the prefix
prefix = ""
- if arg && arg.type == Symbol
+ if arg && arg.class == Symbol
prefix = arg.to_s
- elsif arg && arg.type == String
+ elsif arg && arg.class == String
self.set(arg.sub(/^\$/, ""))
return
end
@@ -158,9 +158,9 @@ def self.go bookmark=nil, options={}
#el4r_lisp_eval "(require 'bookmark)(bookmark-maybe-load-default-file)"
# If arg is a symbol, use it as the prefix
prefix_to_bm = ""
- if bookmark && bookmark.type == Symbol
+ if bookmark && bookmark.class == Symbol
prefix_to_bm = bookmark.to_s
- elsif bookmark && bookmark.type == String
+ elsif bookmark && bookmark.class == String
keys = bookmark
# return self.jump(bookmark.sub(/^\$/, ""))
end
@@ -228,7 +228,6 @@ def self.expand path, options={}
end
end
return path if bm.nil?
-
# If a slash, cut off filename if there is one (only dir is wanted)
if options[:file_ok] # Put slash back if there was one
bm << "/" if bm !~ /\/$/ && slash.any?
@@ -301,13 +300,15 @@ def self.list path=nil
if ! path # Print all bookmarks
all = $el.elvar.bookmark_alist.collect { |bm|
item = bm.to_a
- [item[0], item[1].to_a[0][1]]
+
+ second = item[1] # Either (filename . "/path") or ((filename . "/path") ...)
+ second = second[1].is_a?(String) ? second[1] : second[0][1]
+
+ [item[0], second]
}
all.each do |l|
n, p = l
result << "- #{n}) @#{p.sub(/\/$/,'')}\n"
- # puts "- #{n.ljust(7)} #{p.sub(/\/$/,'')}"
- #puts "- #{n}: #{p}"
end
return result
end
20 lib/xiki/buffers.rb
View
@@ -21,19 +21,19 @@ def self.current *name
case Keys.prefix :clear=>true
# Show all by default
- when nil, "all": return list.map{ |b| $el.buffer_name(b) }.map{ |o| "| #{o}\n" }.join('')
+ when nil, "all"; return list.map{ |b| $el.buffer_name(b) }.map{ |o| "| #{o}\n" }.join('')
# Only files (no buffers)
- when :u: return list.select{ |b| $el.buffer_file_name(b) }.map{ |b| "| #{$el.buffer_name(b)}\n" }.join('')
+ when :u; return list.select{ |b| $el.buffer_file_name(b) }.map{ |b| "| #{$el.buffer_name(b)}\n" }.join('')
# Only buffer without files
- when 0: return list.select{ |b| ! $el.buffer_file_name(b) }.map{ |b| "| #{$el.buffer_name(b)}\n" }[1..-1].join('')
+ when 0; return list.select{ |b| ! $el.buffer_file_name(b) }.map{ |b| "| #{$el.buffer_name(b)}\n" }[1..-1].join('')
- when 1: return list.select{ |b| $el.buffer_file_name(b) }.map{ |b| $el.buffer_name(b) }[1..-1]
- when 3: return list.select{ |b| ! $el.buffer_file_name(b) && $el.buffer_name(b) =~ /^#/ }.map{ |b| $el.buffer_name(b) }
- when 4: return list.select{ |b| ! $el.buffer_file_name(b) && $el.buffer_name(b) =~ /^\*console / }.map{ |b| $el.buffer_name(b) }
- when 6: return list.select{ |b| $el.buffer_file_name(b) =~ /\.rb$/ }.map{ |b| $el.buffer_name(b) }
- when 7: return list.select{ |b| $el.buffer_file_name(b) =~ /\.notes$/ }.map{ |b| $el.buffer_name(b) }
+ when 1; return list.select{ |b| $el.buffer_file_name(b) }.map{ |b| $el.buffer_name(b) }[1..-1]
+ when 3; return list.select{ |b| ! $el.buffer_file_name(b) && $el.buffer_name(b) =~ /^#/ }.map{ |b| $el.buffer_name(b) }
+ when 4; return list.select{ |b| ! $el.buffer_file_name(b) && $el.buffer_name(b) =~ /^\*console / }.map{ |b| $el.buffer_name(b) }
+ when 6; return list.select{ |b| $el.buffer_file_name(b) =~ /\.rb$/ }.map{ |b| $el.buffer_name(b) }
+ when 7; return list.select{ |b| $el.buffer_file_name(b) =~ /\.notes$/ }.map{ |b| $el.buffer_name(b) }
end
return
@@ -132,8 +132,8 @@ def self.from_string name
def self.open_viewing
case Keys.prefix
- when nil: Launcher.open("- Buffers.tree 25/")
- when 0: Launcher.open("- Buffers.tree/")
+ when nil; Launcher.open("- Buffers.tree 25/")
+ when 0; Launcher.open("- Buffers.tree/")
else Launcher.open("- Buffers.tree #{Keys.prefix}/")
end
end
8 lib/xiki/code.rb
View
@@ -1,10 +1,6 @@
require 'xiki/block'
require 'stringio'
-gem 'ruby2ruby'
-require 'ruby2ruby'
-gem 'ParseTree'
-require 'parse_tree'
-require 'parse_tree_extensions' # required for .to_ruby
+
class Code
def self.menu
@@ -643,7 +639,7 @@ def self.enter_log_time
end
def self.to_ruby o
- o.to_ruby
+ o.to_source
end
def self.isearch_just_should
2  lib/xiki/code_tree.rb
View
@@ -104,7 +104,7 @@ def self.run code, options={}
if ! stdout.nonempty? and ! returned.nil?
stdout = self.returned_to_s returned
else
- message(returned.to_s) if returned and (!returned.is_a?(String) or returned.size < 500)
+ $el.message(returned.to_s) if returned and (!returned.is_a?(String) or returned.size < 500)
end
stdout = self.draw_exception(e, code) if e
14 lib/xiki/color.rb
View
@@ -175,21 +175,13 @@ def self.define_styles # For Keys.layout_kolor_light, etc.
return if ! $el
- # Orange path in mode line
- # Blue path in mode line
- # Styles.define :mode_line_dir, :fg=>"7ce", :size=>"0", :face=>"arial", :bold=>false
-
- Styles.define :mode_line_file, :fg=>"fff", :size=>"0", :face=>"arial", :bold=>false
-
- if Styles.inverse
- Styles.define :mode_line_dir, :fg=>"d93", :size=>"0", :face=>"arial", :bold=>false # Brighter
+ if Styles.dark_bg?
Styles.define :color_rb_red, :bg => "500"
Styles.define :color_rb_orange, :bg => "442500"
Styles.define :color_rb_yellow, :bg => "440"
Styles.define :color_rb_green, :bg => "131"
Styles.define :color_rb_white, :fg=>'222', :bg=>'fff', :border=>['fff', -1]
-
Styles.define :color_rb_light, :bg => "252525"
Styles.define :color_rb_blue, :bg => "005"
@@ -197,14 +189,12 @@ def self.define_styles # For Keys.layout_kolor_light, etc.
else
- Styles.define :mode_line_dir, :fg=>"ea4", :size=>"0", :face=>"arial", :bold=>false # Brighter
-
Styles.define :color_rb_red, :bg => "ffd5d5"
Styles.define :color_rb_orange, :bg => "ffe5bb"
Styles.define :color_rb_yellow, :bg => "f9f9aa"
Styles.define :color_rb_green, :bg => "e0ffcc"
- Styles.define :color_rb_light, :bg => "ddd"
Styles.define :color_rb_white, :fg=>'222', :bg=>'666', :border=>['666', -1]
+ Styles.define :color_rb_light, :bg => "ddd"
Styles.define :color_rb_blue, :bg => "dde5ff"
Styles.define :color_rb_purple, :bg => "f2ddff"
6 lib/xiki/console.rb
View
@@ -106,6 +106,8 @@ def self.run command, options={}
result = ""
result << stdout.readlines.join('')
result << stderr.readlines.join('')
+
+ result.force_encoding("binary") if result.respond_to? :force_encoding
result.gsub!("\c@", '.') # Replace out characters that el4r can't handle
return result
@@ -122,6 +124,10 @@ def self.run command, options={}
$el.erase_buffer if reuse_buffer
$el.elvar.default_directory = dir if dir
$el.shell $el.current_buffer
+
+ # Don't prompt with "buffer has a running process" when closing
+ $el.set_process_query_on_exit_flag $el.get_buffer_process($el.current_buffer), nil
+
Move.bottom
if command # If nil, just open console
$el.insert command
6 lib/xiki/control_lock.rb
View
@@ -4,6 +4,10 @@
class ControlLock
def self.disable
- $el.control_lock_enable if $el.boundp(:control_lock_mode_p) and $el.elvar.control_lock_mode_p
+ $el.control_lock_enable if self.enabled?
+ end
+
+ def self.enabled?
+ $el.boundp(:control_lock_mode_p) and $el.elvar.control_lock_mode_p
end
end
4 lib/xiki/control_tab.rb
View
@@ -29,11 +29,13 @@ def self.go
View.layout_output :dont_highlight=>1
Move.to_end
- Search.forward "^-", :go_anyway=>1
+ Search.forward "^ *-", :go_anyway=>1
if View.cursor == View.bottom
Move.to_previous_paragraph
Line.next
end
+
+ Line.to_beginning
Effects.blink
Launcher.launch
@@nine_prefix = true
8 lib/xiki/core_ext.rb
View
@@ -18,11 +18,15 @@ def blank?
class String
def blank?
- self.nil? || self.empty?
+ empty?
end
def present?
- ! self.nil?
+ ! empty?
+ end
+
+ def any?
+ ! empty?
end
def unindent
9 lib/xiki/cursor.rb
View
@@ -7,23 +7,23 @@ def self.menu
> Summary
| Api for changing the cursor
|
- - Colors/
+ - colors/
@Cursor.white
@Cursor.red
@Cursor.green
@Cursor.blue
@Cursor.color "#80f"
- - Shapes/
+ - shapes/
@Cursor.bar
@Cursor.underscore
@Cursor.hollow
@Cursor.box
- - Colors and Shapes/
+ - colors and shapes/
@Cursor.red_bar
@Cursor.green_underscore
@Cursor.blue_hollow
@Cursor.black_box
- - Remembering and restoring cursor/
+ - remembering and restoring cursor/
@Cursor.remember :a
@Cursor.restore :a
`
@@ -103,7 +103,6 @@ def self.restore symbol=:default
before = @@remember[symbol]
return Cursor.black_box unless before # Black if not found
type, color = before
- $el.set_face_background :cursor, color
$el.customize_set_variable :cursor_type, type
end
6 lib/xiki/diff_log.rb
View
@@ -41,7 +41,7 @@ def self.open
def self.diffs path=nil
- txt = File.read @@log
+ txt = File.open(@@log, 'rb') {|f| f.read}
txt = txt.sub(/\A- /, '').split(/^- /).reverse.uniq
path ||= Tree.dir # Pull from tree if there
@@ -201,8 +201,8 @@ def self.save_diffs options={}
diff = Console.sync "diff -U 0 \"#{patha}\" \"#{@@temp_path}\""
return if diff.empty? || diff =~ /: No such file or directory\n/ # Fail quietly if file didn't exist
- diff = self.format diff
- return diff if options[:dont_log]
+ diff = self.format(diff) rescue nil
+ return diff if diff.nil? || options[:dont_log]
File.open(@@log, "a") { |f| f << diff } unless diff.count("\n") <= 2
end
5 lib/xiki/effects.rb
View
@@ -43,6 +43,9 @@ def self.menu
"
end
+ #
+ # Effects.glow :color=>:forest
+ #
def self.glow options={}
what = options[:what]
@@ -91,7 +94,7 @@ def self.glow options={}
sequence.each do |i|
$el.overlay_put over, :face, (faces[i-1] || faces[0])
- $el.sit_for 0.02
+ $el.sit_for 0.0005
end
$el.delete_overlay over
50 lib/xiki/file_tree.rb
View
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
require 'xiki/styles'
require 'xiki/line'
require 'xiki/view'
@@ -164,8 +166,12 @@ def self.grep_with_hashes path, regex, prepend='##'
def self.grep_one_file(f, regex, indent)
result = []
- IO.foreach(f) do |line|
- line.gsub!(/[\r\n\c@]+/, '')
+
+ return result if f =~ /\.(ai|icns|png|gif|jpg|gem)$/
+
+ IO.foreach(f, *Files.encoding_binary) do |line|
+ # line.gsub!(/[\r\n\c@]+/, '')
+ line.chomp!
if regex
next unless line =~ regex
end
@@ -178,7 +184,7 @@ def self.outline_search(f, regex, indent)
result = []
current_line = Search.outline_goto_once # If search_outline, we want to put cursor on that line when done
line_found, matches_count, i = nil, 0, 0
- IO.foreach(f) do |line|
+ IO.foreach(f, *Files.encoding_binary) do |line|
i+=1
line.gsub!(/[\r\n\c@]+/, '')
@@ -267,7 +273,7 @@ def self.define_styles
return if ! $el
- if Styles.inverse # Bullets
+ if Styles.dark_bg? # Bullets
Styles.define :ls_bullet,
:face => 'courier', :size => "+2", # Mac
:fg => "dd7700", :bold => true
@@ -278,9 +284,9 @@ def self.define_styles
end
- if Styles.inverse
- Styles.define :quote_heading, :fg=>"fff", :size=>"0", :face=>"arial", :bold=>false
- Styles.define :quote_heading2, :fg=>"fff", :size=>"-2", :face=>"arial", :bold=>false
+ if Styles.dark_bg?
+ Styles.define :quote_heading, :fg=>"fff", :size=>"0", :face=>"arial", :bold=>true
+ Styles.define :quote_heading2, :fg=>"fff", :size=>"-2", :face=>"arial", :bold=>true
Styles.define :quote_heading_pipe, :fg=>"333", :size=>"0", :face => "verdana", :bold=>true
Styles.define :quote_heading_bracket, :fg=>"4c4c4c", :size=>"-2", :face => "Monaco", :bold=>true
Styles.define :quote_heading_small, :fg=>"fff", :size=>"-2", :face => "arial black", :bold=>true
@@ -297,8 +303,8 @@ def self.define_styles
# Styles.define :ls_dir, :fg => "bbb", :face => "verdana", :size => "-2", :bold => true
else
- Styles.define :quote_heading, :fg=>"444", :size=>"0", :face=>"arial", :bold=>false
- Styles.define :quote_heading2, :fg=>"aaa", :size=>"-2", :face=>"arial", :bold=>false
+ Styles.define :quote_heading, :fg=>"444", :size=>"0", :face=>"arial", :bold=>true
+ Styles.define :quote_heading2, :fg=>"aaa", :size=>"-2", :face=>"arial", :bold=>true
Styles.define :quote_heading_pipe, :fg=>"bbb", :size=>"0", :face => "verdana", :bold=>true
Styles.define :quote_heading_bracket, :fg=>"bbb", :size=>"-2", :face => "Monaco", :bold=>true
Styles.define :quote_heading_small, :fg=>"fff", :size=>"-2", :face => "arial black", :bold=>true
@@ -322,7 +328,7 @@ def self.define_styles
:size => "-2",
:bold => true
- if Styles.inverse # | Quoted text
+ if Styles.dark_bg? # | Quoted text
Styles.define :ls_quote,
:size => "-1",
:fg => "aaa"
@@ -425,12 +431,14 @@ def self.apply_styles_at_end
end
def self.handles? list=nil
- begin
- list ||= Tree.construct_path(:list=>true) # Use current line by default
- rescue Exception=>e
- return nil
+
+ if list.nil?
+ list ||= Tree.construct_path(:list=>true) rescue nil # Use current line by default
end
- return 0 if self.matches_root_pattern?(Line.without_label :line=>list.first)
+
+ list = list.first if list.is_a?(Array)
+
+ return 0 if self.matches_root_pattern?(Line.without_label :line=>list)
nil
end
@@ -1103,7 +1111,7 @@ def self.enter_quote txt=nil
if Line.blank?
if prefix == :u || txt =~ /\A +[-+]?\|[-+ ]/ # If C-u or whole thing is quoted already, unquote
- txt = txt.grep(/\|/).join()
+ txt = txt.split("\n").grep(/\|/).join("\n")
return $el.insert(txt.gsub(/^ *[-+]?\|([-+ ]|$)/, "")) # Remove | ..., |+...., |<blank>, etc
end
@@ -1276,7 +1284,7 @@ def self.enter_lines pattern=nil, options={}
return
end
- IO.foreach(path) do |line|
+ IO.foreach(path, *Files.encoding_binary) do |line|
i+=1
line.sub!(/[\r\n]+$/, '')
@@ -1479,9 +1487,8 @@ def self.one_view_in_bar_by_default= to
def self.copy_path options={}
Effects.blink :what=>:line
-
# Return dir of view's file if at left margin, U, or not ^[|@-]
- if Line !~ /^ +[|@+-]/ || Keys.prefix_u
+ if Line !~ /^ +[|@+-]/ # || Keys.prefix_u# It will never be :u, because the prefix is cleared before this is called
path = View.file
else
path = Xiki.trunk.last # Grab from wiki tree
@@ -1634,6 +1641,9 @@ def self.delete_file
Effects.glow :fade_out=>1
Line.delete
Line.to_beginning
+
+ View.message "File deleted"
+
end
def self.move_latest_screenshot_to dest_path, dest_dir
@@ -1854,7 +1864,7 @@ def self.to_outline
when 0
# Just show path if 0+...
when :- # Just show # foo... comments...
- self.enter_lines(/(^ *def |(^| )# .+\.\.\.$)/, :current_line=>current_line)
+ self.enter_lines(/(^ *def |(^| )(#|"|\/\/) .+\.\.\.$)/, :current_line=>current_line)
when 6 # Just show # foo... comments...
self.enter_lines(/(^ *def |self\.)/, :current_line=>current_line)
when :u
20 lib/xiki/files.rb
View
@@ -181,16 +181,16 @@ def self.open_last
def self.open_edited
case Keys.prefix
- when :u, 8: Launcher.open("- edited/tree/")
+ when :u, 8; Launcher.open("- edited/tree/")
else Launcher.open("- edited/")
end
end
def self.open_history
case Keys.prefix
- when nil: Keys.prefix = nil; Launcher.open("- Files.history/")
- when 0: Launcher.open("- Files.history_tree/")
- when :u: Launcher.open("- Files.history_tree 7/")
+ when nil; Keys.prefix = nil; Launcher.open("- Files.history/")
+ when 0; Launcher.open("- Files.history_tree/")
+ when :u; Launcher.open("- Files.history_tree 7/")
else Launcher.open("- Files.history_tree #{Keys.prefix}/")
end
end
@@ -308,7 +308,7 @@ def self.delete_current_file
return View.beep("- There's no file for this buffer!") if ! dest_path
View.beep :times=>3
- View.flash "- Delete CURRENT file for sure?", :times=>4
+ View.flash "- Delete CURRENT file (#{View.name})?", :times=>4
answer = Keys.input :chars=>1, :prompt=>"- Delete current file for sure?" #"
return View.flash("- cancelled!") if answer !~ /y/i
@@ -326,6 +326,16 @@ def self.delete_current_file
end
+ if /^1\.9/===RUBY_VERSION
+ def self.encoding_binary
+ [{:encoding => 'binary'}]
+ end
+ else
+ def self.encoding_binary
+ []
+ end
+ end
+
end
if $el
1  lib/xiki/history.rb
View
@@ -26,6 +26,7 @@ def self.open_current options={}
elsif options[:prompt_for_bookmark]
bm = Keys.input(:timed => true, :prompt => "Enter bookmark to show content for: ")
path = Bookmarks.expand(bm, :just_bookmark => true)
+ return View.beep("- Bookmark '#{bm}' not found!") if ! path
path = File.expand_path(path)
if ! options[:all] && View.files.member?(path)
11 lib/xiki/key_bindings.rb
View
@@ -163,7 +163,6 @@ def self.enter_keys
Keys.enter_file_path { Files.enter_file } # Given a bookmark
Keys.enter_firefox_tabs { Launcher.insert('- Firefox.tabs/') } # Given a bookmark
Keys.enter_history { DiffLog.enter_from_difflog } # Save point and go to difflog to search
- Keys.enter_insert_1 { Notes.enter_do_bullet } # insert date string (and time if C-u)
Keys.enter_insert_date { View.enter_date }
Keys.enter_insert_comment { Code.enter_insert_comment } # insert date string (and time if C-u)
Keys.enter_insert_new { DiffLog.enter_new } # Enter Old: enter newly-deleted from last save
@@ -195,7 +194,7 @@ def self.enter_keys
Keys.enter_like_variable { insert "\#{#{Clipboard.get(0)}}" }
Keys.enter_menu { Xiki.insert_menu } # Redundant with C-enter on blank line
- Keys.enter_note { Notes.enter_do_bullet } # Redundant with C-enter on blank line
+ Keys.enter_note { Notes.enter_note } # Redundant with C-enter on blank line
Keys.enter_outline { Launcher.enter_outline } # in tree, enter methods or headings
Keys.enter_push { Gito.code_tree_diff(:enter=>true) } # Commit to repos, push, etc
@@ -639,8 +638,12 @@ def self.misc
$el.el4r_lisp_eval("(require 'dired)")
$el.define_key :dired_mode_map, $el.kbd("C-o"), nil
$el.define_key :java_mode_map, $el.kbd("C-d"), nil
- $el.el_require :php_mode
- $el.define_key :php_mode_map, $el.kbd("C-d"), nil
+
+ begin
+ $el.el_require :php_mode
+ $el.define_key :php_mode_map, $el.kbd("C-d"), nil
+ rescue Exception=>e
+ end
# C-l in ediff mode
$el.defun(:ediff_disable_C_l) { $el.define_key(:ediff_mode_map, $el.kbd("C-l"), nil) }
58 lib/xiki/keys.rb
View
@@ -297,40 +297,28 @@ def self.set *args, &block
#
# Sample usages:
# Keys.input # Terminated by enter
+ # Keys.input "Type something: "
# Keys.input :chars=>1 # Just one char
- # Keys.input :control=>1 # One char if control
# Keys.input :timed=>1 # Terminated by pause
# Keys.input :optional=>1 # Terminated by pause
# - A pause at the beginning will result in no input (nil)
#
- def self.input options={}
+ def self.input *args
+
+ prompt = args.shift if args[0].is_a?(String)
+
+ options = args[0] || {}
return self.input_with_choices(options) if options[:choices]
Cursor.remember :before_input
- Cursor.green
- Cursor.hollow
- prompt = options[:prompt] || "Input: "
+ # This is slow in mac emacs 23/24 :(
+ # Cursor.green
- # Not completely implemented
- if options[:control]
- prompt = "todo - implement this: "
-
- $el.elvar.inhibit_quit = true
- # Maybe use this?
- # Or call self.char?
- # char = $el.char_to_string(Keys.remove_control($el.read_char(prompt))).to_s
- c = read_char(prompt)
- $el.elvar.inhibit_quit = nil
- if c == 7
- Cursor.restore :before_input
- keyboard_quit
- end
+ Cursor.hollow
- Cursor.restore :before_input
- return c
- end
+ prompt ||= options[:prompt] || "Input: "
if options[:chars]
char = $el.char_to_string(
@@ -375,7 +363,6 @@ def self.input options={}
Cursor.restore :before_input
$el.message ""
-
# If nothing, return nil
keys == "" ? nil : keys
end
@@ -392,9 +379,10 @@ def self.input_with_choices options
def self.to_letter ch
return nil if ch.nil?
- if ch < 27
+ if ch == 0
+ ch = 32
+ elsif ch < 27
ch += 96
-
elsif 67108896 <= ch and ch <= 67108921
ch -= 67108864
end
@@ -496,7 +484,9 @@ def self.timed_insert options={}
end
Cursor.remember :before_q
- Cursor.green
+ Cursor.box
+ # This is slow in mac emacs 23/24 :(
+ # Cursor.green
# Get first char and insert