Merge commit 'origin/master'

db4
Jose A. Ortega Ruiz 2008-12-22 03:53:57 +01:00
commit 034c8f6cb3
28 changed files with 513 additions and 198 deletions

View File

@ -85,13 +85,13 @@ IN: formatting.tests
[ t ] [ "12:03:15" testtime "%H:%M:%S" strftime = ] unit-test [ t ] [ "12:03:15" testtime "%H:%M:%S" strftime = ] unit-test
[ t ] [ "12:03:15" testtime "%X" strftime = ] unit-test [ t ] [ "12:03:15" testtime "%X" strftime = ] unit-test
[ t ] [ "10/09/2008" testtime "%m/%d/%Y" strftime = ] unit-test [ t ] [ "10/09/2008" testtime "%m/%d/%Y" strftime = ] unit-test
[ t ] [ "10/09/2008" testtime "%x" strftime = ] unit-test [ t ] [ "10/09/2008" testtime "%x" strftime = ] unit-test
[ t ] [ "10/09/08" testtime "%m/%d/%y" strftime = ] unit-test
[ t ] [ "Thu" testtime "%a" strftime = ] unit-test [ t ] [ "Thu" testtime "%a" strftime = ] unit-test
[ t ] [ "Thursday" testtime "%A" strftime = ] unit-test [ t ] [ "Thursday" testtime "%A" strftime = ] unit-test
[ t ] [ "Oct" testtime "%b" strftime = ] unit-test [ t ] [ "Oct" testtime "%b" strftime = ] unit-test
[ t ] [ "October" testtime "%B" strftime = ] unit-test [ t ] [ "October" testtime "%B" strftime = ] unit-test
[ t ] [ "Thu Oct 09 12:03:15 2008" testtime "%c" strftime = ] unit-test
[ t ] [ "PM" testtime "%p" strftime = ] unit-test

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license ! See http://factorcode.org/license.txt for BSD license
USING: accessors arrays ascii calendar combinators fry kernel USING: accessors arrays ascii calendar combinators fry kernel
io io.encodings.ascii io.files io.streams.string generalizations io io.encodings.ascii io.files io.streams.string
macros math math.functions math.parser peg.ebnf quotations macros math math.functions math.parser peg.ebnf quotations
sequences splitting strings unicode.case vectors ; sequences splitting strings unicode.case vectors ;
@ -32,10 +32,7 @@ IN: formatting
[ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." glue ; [ "." split1 ] dip [ CHAR: 0 pad-right ] [ head-slice ] bi "." glue ;
: max-digits ( n digits -- n' ) : max-digits ( n digits -- n' )
10 swap ^ [ * round ] keep / ; 10 swap ^ [ * round ] keep / ; inline
: max-width ( string length -- string' )
short head ;
: >exp ( x -- exp base ) : >exp ( x -- exp base )
[ [
@ -69,7 +66,7 @@ pad = pad-align pad-char pad-width => [[ reverse >quotation dup first 0 =
sign = ("+")? => [[ [ dup CHAR: - swap index [ "+" prepend ] unless ] [ ] ? ]] sign = ("+")? => [[ [ dup CHAR: - swap index [ "+" prepend ] unless ] [ ] ? ]]
width_ = "." ([0-9])* => [[ second >digits '[ _ max-width ] ]] width_ = "." ([0-9])* => [[ second >digits '[ _ short head ] ]]
width = (width_)? => [[ [ ] or ]] width = (width_)? => [[ [ ] or ]]
digits_ = "." ([0-9])* => [[ second >digits ]] digits_ = "." ([0-9])* => [[ second >digits ]]
@ -113,23 +110,25 @@ MACRO: printf ( format-string -- )
<PRIVATE <PRIVATE
: zero-pad ( str -- str' ) 2 CHAR: 0 pad-left ; inline : pad-00 ( n -- string ) number>string 2 CHAR: 0 pad-left ; inline
: pad-000 ( n -- string ) number>string 3 CHAR: 0 pad-left ; inline
: >time ( timestamp -- string ) : >time ( timestamp -- string )
[ hour>> ] [ minute>> ] [ second>> floor ] tri 3array [ hour>> ] [ minute>> ] [ second>> floor ] tri 3array
[ number>string zero-pad ] map ":" join ; inline [ pad-00 ] map ":" join ; inline
: >date ( timestamp -- string ) : >date ( timestamp -- string )
[ month>> ] [ day>> ] [ year>> ] tri 3array [ month>> ] [ day>> ] [ year>> ] tri 3array
[ number>string zero-pad ] map "/" join ; inline [ pad-00 ] map "/" join ; inline
: >datetime ( timestamp -- string ) : >datetime ( timestamp -- string )
{ [ day-of-week day-abbreviation3 ] { [ day-of-week day-abbreviation3 ]
[ month>> month-abbreviation ] [ month>> month-abbreviation ]
[ day>> number>string zero-pad ] [ day>> pad-00 ]
[ >time ] [ >time ]
[ year>> number>string ] [ year>> number>string ]
} cleave 3array [ 2array ] dip append " " join ; inline } cleave 5 narray " " join ; inline
: (week-of-year) ( timestamp day -- n ) : (week-of-year) ( timestamp day -- n )
[ dup clone 1 >>month 1 >>day day-of-week dup ] dip > [ 7 swap - ] when [ dup clone 1 >>month 1 >>day day-of-week dup ] dip > [ 7 swap - ] when
@ -147,20 +146,20 @@ fmt-A = "A" => [[ [ dup day-of-week day-name ] ]]
fmt-b = "b" => [[ [ dup month>> month-abbreviation ] ]] fmt-b = "b" => [[ [ dup month>> month-abbreviation ] ]]
fmt-B = "B" => [[ [ dup month>> month-name ] ]] fmt-B = "B" => [[ [ dup month>> month-name ] ]]
fmt-c = "c" => [[ [ dup >datetime ] ]] fmt-c = "c" => [[ [ dup >datetime ] ]]
fmt-d = "d" => [[ [ dup day>> number>string zero-pad ] ]] fmt-d = "d" => [[ [ dup day>> pad-00 ] ]]
fmt-H = "H" => [[ [ dup hour>> number>string zero-pad ] ]] fmt-H = "H" => [[ [ dup hour>> pad-00 ] ]]
fmt-I = "I" => [[ [ dup hour>> dup 12 > [ 12 - ] when number>string zero-pad ] ]] fmt-I = "I" => [[ [ dup hour>> dup 12 > [ 12 - ] when pad-00 ] ]]
fmt-j = "j" => [[ [ dup day-of-year number>string ] ]] fmt-j = "j" => [[ [ dup day-of-year pad-000 ] ]]
fmt-m = "m" => [[ [ dup month>> number>string zero-pad ] ]] fmt-m = "m" => [[ [ dup month>> pad-00 ] ]]
fmt-M = "M" => [[ [ dup minute>> number>string zero-pad ] ]] fmt-M = "M" => [[ [ dup minute>> pad-00 ] ]]
fmt-p = "p" => [[ [ dup hour>> 12 < "AM" "PM" ? ] ]] fmt-p = "p" => [[ [ dup hour>> 12 < "AM" "PM" ? ] ]]
fmt-S = "S" => [[ [ dup second>> round number>string zero-pad ] ]] fmt-S = "S" => [[ [ dup second>> floor pad-00 ] ]]
fmt-U = "U" => [[ [ dup week-of-year-sunday ] ]] fmt-U = "U" => [[ [ dup week-of-year-sunday pad-00 ] ]]
fmt-w = "w" => [[ [ dup day-of-week number>string ] ]] fmt-w = "w" => [[ [ dup day-of-week number>string ] ]]
fmt-W = "W" => [[ [ dup week-of-year-monday ] ]] fmt-W = "W" => [[ [ dup week-of-year-monday pad-00 ] ]]
fmt-x = "x" => [[ [ dup >date ] ]] fmt-x = "x" => [[ [ dup >date ] ]]
fmt-X = "X" => [[ [ dup >time ] ]] fmt-X = "X" => [[ [ dup >time ] ]]
fmt-y = "y" => [[ [ dup year>> 100 mod number>string ] ]] fmt-y = "y" => [[ [ dup year>> 100 mod pad-00 ] ]]
fmt-Y = "Y" => [[ [ dup year>> number>string ] ]] fmt-Y = "Y" => [[ [ dup year>> number>string ] ]]
fmt-Z = "Z" => [[ [ "Not yet implemented" throw ] ]] fmt-Z = "Z" => [[ [ "Not yet implemented" throw ] ]]
unknown = (.)* => [[ "Unknown directive" throw ]] unknown = (.)* => [[ "Unknown directive" throw ]]

View File

@ -1,7 +1,7 @@
USING: io.directories io.files.links tools.test sequences USING: io.directories io.files.links tools.test sequences
io.files.unique tools.files fry math kernel math.parser io.files.unique tools.files fry math kernel math.parser
io.pathnames namespaces ; io.pathnames namespaces ;
IN: io.files.links.tests IN: io.files.links.unix.tests
: make-test-links ( n path -- ) : make-test-links ( n path -- )
[ '[ [ 1+ ] keep [ number>string _ prepend ] bi@ make-link ] each ] [ '[ [ 1+ ] keep [ number>string _ prepend ] bi@ make-link ] each ]

View File

@ -13,7 +13,7 @@ HELP: parse-log
} ; } ;
ARTICLE: "logging.parser" "Log file parser" ARTICLE: "logging.parser" "Log file parser"
"The " { $vocab-link "logging.parser" } " vocabulary parses log files output by the " { $vocab-link "logging" } " vocabulary. It is used by " { $link "logging.analysis" } " and " { $link "logging.insomniac" } " to analyze logs." "The " { $vocab-link "logging.parser" } " vocabulary parses log files output by the " { $vocab-link "logging" } " vocabulary. It is used by " { $link "logging.analysis" } " and " { $vocab-link "logging.insomniac" } " to analyze logs."
$nl $nl
"There is only one primary entry point:" "There is only one primary entry point:"
{ $subsection parse-log } ; { $subsection parse-log } ;

View File

@ -2,14 +2,18 @@ USING: tools.profiler.private tools.time help.markup help.syntax
quotations io strings words definitions ; quotations io strings words definitions ;
IN: tools.profiler IN: tools.profiler
ARTICLE: "profiling" "Profiling code" ARTICLE: "profiler-limitations" "Profiler limitations"
"The " { $vocab-link "tools.profiler" } " vocabulary implements a simple call counting profiler. The profiler is completely accurate with words and methods which are compiled with the non-optimizing compiler. Some optimizations performed by the optimizing compiler can inhibit accurate call counting, however:" "Certain optimizations performed by the compiler can inhibit accurate call counting:"
{ $list { $list
"The optimizing compiler open-codes certain primitives with inline machine code, and in some cases optimizes them out altogether; this includes stack shuffling operations, conditionals, and many object allocation operations." "Calls to open-coded intrinsics are not counted. Certain words are open-coded as inline machine code, and in some cases optimized out altogether; this includes stack shuffling operations, conditionals, and many object allocation operations."
{ "Calls to " { $link POSTPONE: inline } " words are not counted.." } { "Calls to " { $link POSTPONE: inline } " words are not counted." }
{ "Calls to methods which were inlined as a result of type inference are not counted." } { "Calls to methods which were inlined as a result of type inference are not counted." }
"Tail-recursive loops will only count the initial invocation of the word, not every tail call." "Tail-recursive loops will only count the initial invocation of the word, not every tail call."
} } ;
ARTICLE: "profiling" "Profiling code"
"The " { $vocab-link "tools.profiler" } " vocabulary implements a simple call counting profiler."
$nl
"Quotations can be passed to a combinator which calls them with the profiler enabled:" "Quotations can be passed to a combinator which calls them with the profiler enabled:"
{ $subsection profile } { $subsection profile }
"After a quotation has been profiled, call counts can be presented in various ways:" "After a quotation has been profiled, call counts can be presented in various ways:"
@ -17,7 +21,9 @@ ARTICLE: "profiling" "Profiling code"
{ $subsection vocab-profile. } { $subsection vocab-profile. }
{ $subsection usage-profile. } { $subsection usage-profile. }
{ $subsection vocabs-profile. } { $subsection vocabs-profile. }
{ $subsection method-profile. } ; { $subsection method-profile. }
{ $subsection "profiler-limitations" }
{ $see-also "ui-profiler" } ;
ABOUT: "profiling" ABOUT: "profiling"

1
basis/uuid/authors.txt Normal file
View File

@ -0,0 +1 @@
John Benediktsson

1
basis/uuid/summary.txt Normal file
View File

@ -0,0 +1 @@
Generates UUID's.

View File

@ -0,0 +1,45 @@
USING: help.syntax help.markup kernel prettyprint sequences strings ;
IN: uuid
HELP: uuid1
{ $description
"Generates a UUID (version 1) from the host ID, sequence number, "
"and current time."
} ;
HELP: uuid3
{ $description
"Generates a UUID (version 3) from the MD5 hash of a namespace "
"UUID and a name."
} ;
HELP: uuid4
{ $description
"Generates a UUID (version 4) from random bits."
} ;
HELP: uuid5
{ $description
"Generates a UUID (version 5) from the SHA-1 hash of a namespace "
"UUID and a name."
} ;
ARTICLE: "uuid" "UUID (Universally Unique Identifier)"
"The " { $vocab-link "uuid" } " vocabulary is used to generate UUID's. "
"The words uuid1, uuid3, uuid4, uuid5 can be used to generate version "
"1, 3, 4, and 5 UUIDs as specified in RFC 4122.\n"
"\n"
"If all you want is a unique ID, you should probably call uuid1 or uuid4."
"\n"
{ $subsection uuid1 }
{ $subsection uuid3 }
{ $subsection uuid4 }
{ $subsection uuid5 }
;
ABOUT: "uuid"

View File

@ -0,0 +1,18 @@
! Copyright (C) 2008 John Benediktsson
! See http://factorcode.org/license.txt for BSD license
USING: kernel uuid tools.test ;
IN: uuid.tests
[ t ] [ NAMESPACE_DNS [ uuid-parse uuid-unparse ] keep = ] unit-test
[ t ] [ NAMESPACE_URL [ uuid-parse uuid-unparse ] keep = ] unit-test
[ t ] [ NAMESPACE_OID [ uuid-parse uuid-unparse ] keep = ] unit-test
[ t ] [ NAMESPACE_X500 [ uuid-parse uuid-unparse ] keep = ] unit-test
[ t ] [ NAMESPACE_URL "ABCD" uuid3
"2e10e403-d7fa-3ffb-808f-ab834a46890e" = ] unit-test
[ t ] [ NAMESPACE_URL "ABCD" uuid5
"0aa883d6-7953-57e7-a8f0-66db29ce5a91" = ] unit-test

94
basis/uuid/uuid.factor Normal file
View File

@ -0,0 +1,94 @@
! Copyright (C) 2008 John Benediktsson
! See http://factorcode.org/license.txt for BSD license
USING: byte-arrays checksums checksums.md5 checksums.sha1
kernel math math.parser math.ranges random unicode.case
sequences strings system ;
IN: uuid
<PRIVATE
: (timestamp) ( -- time_high time_mid time_low )
! 0x01b21dd213814000L is the number of 100-ns intervals
! between the UUID epoch 1582-10-15 00:00:00 and the
! Unix epoch 1970-01-01 00:00:00.
micros 10 * HEX: 01b21dd213814000 +
[ -48 shift HEX: 0fff bitand ]
[ -32 shift HEX: ffff bitand ]
[ HEX: ffffffff bitand ] tri ;
: (hardware) ( -- address )
! Choose a random 48-bit number with eighth bit
! set to 1 (as recommended in RFC 4122)
48 random-bits HEX: 010000000000 bitor ;
: (clock) ( -- clockseq )
! Choose a random 14-bit number
14 random-bits ;
: <uuid> ( address clockseq time_high time_mid time_low -- n )
96 shift
[ 80 shift ] dip bitor
[ 64 shift ] dip bitor
[ 48 shift ] dip bitor
bitor ;
: (version) ( n version -- n' )
[ HEX: c000 48 shift bitnot bitand
HEX: 8000 48 shift bitor
HEX: f000 64 shift bitnot bitand
] dip 76 shift bitor ;
: uuid>string ( n -- string )
>hex 32 CHAR: 0 pad-left
[ CHAR: - 20 ] dip insert-nth
[ CHAR: - 16 ] dip insert-nth
[ CHAR: - 12 ] dip insert-nth
[ CHAR: - 8 ] dip insert-nth ;
: string>uuid ( string -- n )
[ CHAR: - = not ] filter 16 base> ;
: uuid>byte-array ( n -- byte-array )
16 <byte-array> 15 -1 [a,b) [
[ dup HEX: ff bitand ] 2dip swap
[ set-nth -8 shift ] keep
] each nip ;
: byte-array>uuid ( byte-array -- n )
0 swap [ [ 8 shift ] dip + ] each ;
PRIVATE>
: uuid-parse ( string -- byte-array )
string>uuid uuid>byte-array ;
: uuid-unparse ( byte-array -- string )
byte-array>uuid uuid>string ;
: uuid1 ( -- string )
(hardware) (clock) (timestamp) <uuid>
1 (version) uuid>string ;
: uuid3 ( namespace name -- string )
[ uuid-parse ] dip >byte-array append
md5 checksum-bytes 16 short head byte-array>uuid
3 (version) uuid>string ;
: uuid4 ( -- string )
128 random-bits
4 (version) uuid>string ;
: uuid5 ( namespace name -- string )
[ uuid-parse ] dip >byte-array append
sha1 checksum-bytes 16 short head byte-array>uuid
5 (version) uuid>string ;
: NAMESPACE_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ; inline
: NAMESPACE_URL "6ba7b811-9dad-11d1-80b4-00c04fd430c8" ; inline
: NAMESPACE_OID "6ba7b812-9dad-11d1-80b4-00c04fd430c8" ; inline
: NAMESPACE_X500 "6ba7b814-9dad-11d1-80b4-00c04fd430c8" ; inline

View File

@ -3,18 +3,20 @@ USING: help.markup help.syntax vocabs.loader words io
quotations words.symbol ; quotations words.symbol ;
ARTICLE: "compiler-errors" "Compiler warnings and errors" ARTICLE: "compiler-errors" "Compiler warnings and errors"
"The compiler saves various notifications in a global variable:" "The compiler saves " { $link "inference-errors" } " in a global variable:"
{ $subsection compiler-errors } { $subsection compiler-errors }
"These notifications can be viewed later:" "These notifications can be viewed later:"
{ $subsection :errors } { $subsection :errors }
{ $subsection :warnings } { $subsection :warnings }
{ $subsection :linkage } { $subsection :linkage }
"Words such as " { $link require } " use a combinator which counts errors and prints a report at the end:" "Words such as " { $link require } " use a combinator which counts errors and prints a report at the end:"
{ $link with-compiler-errors } ; { $subsection with-compiler-errors } ;
HELP: compiler-errors HELP: compiler-errors
{ $var-description "Global variable holding an assoc mapping words to compiler errors. This variable is set by " { $link with-compiler-errors } "." } ; { $var-description "Global variable holding an assoc mapping words to compiler errors. This variable is set by " { $link with-compiler-errors } "." } ;
ABOUT: "compiler-errors"
HELP: compiler-error HELP: compiler-error
{ $values { "error" "an error" } { "word" word } } { $values { "error" "an error" } { "word" word } }
{ $description "If inside a " { $link with-compiler-errors } ", saves the error for future persual via " { $link :errors } ", " { $link :warnings } " and " { $link :linkage } ". If not inside a " { $link with-compiler-errors } ", ignores the error." } ; { $description "If inside a " { $link with-compiler-errors } ", saves the error for future persual via " { $link :errors } ", " { $link :warnings } " and " { $link :linkage } ". If not inside a " { $link with-compiler-errors } ", ignores the error." } ;

View File

@ -1,7 +1,7 @@
USING: arrays byte-arrays kernel kernel.private math memory USING: arrays byte-arrays kernel kernel.private math memory
namespaces sequences tools.test math.private quotations namespaces sequences tools.test math.private quotations
continuations prettyprint io.streams.string debugger assocs continuations prettyprint io.streams.string debugger assocs
sequences.private accessors ; sequences.private accessors locals.backend ;
IN: kernel.tests IN: kernel.tests
[ 0 ] [ f size ] unit-test [ 0 ] [ f size ] unit-test
@ -35,7 +35,7 @@ IN: kernel.tests
[ ] [ [ :c ] with-string-writer drop ] unit-test [ ] [ [ :c ] with-string-writer drop ] unit-test
: overflow-r 3 [ overflow-r ] dip ; : overflow-r 3 load-local overflow-r ;
[ overflow-r ] [ { "kernel-error" 14 f f } = ] must-fail-with [ overflow-r ] [ { "kernel-error" 14 f f } = ] must-fail-with

View File

@ -122,8 +122,8 @@ M: source-file fuel-pprint path>> fuel-pprint ;
fuel-forget-result fuel-forget-result
fuel-forget-output ; fuel-forget-output ;
: (fuel-end-eval) ( quot -- ) : (fuel-end-eval) ( result -- )
with-string-writer fuel-eval-output set-global fuel-retort fuel-eval-output set-global fuel-retort
pop-fuel-status ; inline pop-fuel-status ; inline
: (fuel-eval) ( lines -- ) : (fuel-eval) ( lines -- )
@ -141,39 +141,29 @@ M: source-file fuel-pprint path>> fuel-pprint ;
[ dup "IN: " prepend 1vector (fuel-eval) in set ] when* ; inline [ dup "IN: " prepend 1vector (fuel-eval) in set ] when* ; inline
: fuel-eval-in-context ( lines in usings -- ) : fuel-eval-in-context ( lines in usings -- )
(fuel-begin-eval) [
(fuel-eval-usings)
(fuel-eval-in)
(fuel-eval)
] (fuel-end-eval) ;
: fuel-begin-eval ( in -- )
(fuel-begin-eval) (fuel-begin-eval)
(fuel-eval-in) [ (fuel-eval-usings) (fuel-eval-in) (fuel-eval) ] with-string-writer
fuel-retort ; (fuel-end-eval) ;
: fuel-eval ( lines -- )
(fuel-begin-eval) [ (fuel-eval) ] (fuel-end-eval) ; inline
: fuel-end-eval ( -- ) [ ] (fuel-end-eval) ; inline
: fuel-run-file ( path -- ) run-file ; inline : fuel-run-file ( path -- ) run-file ; inline
! Edit locations ! Edit locations
: fuel-get-edit-location ( defspec -- ) : fuel-normalize-loc ( seq -- path line )
where [ dup length 1 > [ first2 [ (normalize-path) ] dip ] [ f ] if ; inline
first2 [ (normalize-path) ] dip 2array fuel-eval-set-result
] when* ; inline
: fuel-xref-desc ( word -- str ) : fuel-get-edit-location ( defspec -- )
[ name>> ] where fuel-normalize-loc 2array fuel-eval-set-result ; inline
[ vocabulary>> [ " (" prepend ")" append ] [ "" ] if* ] bi append ; inline
: fuel-get-doc-location ( defspec -- )
props>> "help-loc" swap at
fuel-normalize-loc 2array fuel-eval-set-result ;
: fuel-format-xrefs ( seq -- seq ) : fuel-format-xrefs ( seq -- seq )
[ word? ] filter [ [ word? ] filter [
[ fuel-xref-desc ] [ name>> ]
[ where [ first2 [ (normalize-path) ] dip ] [ f f ] if* ] bi 3array [ vocabulary>> ]
[ where fuel-normalize-loc ] tri 4array
] map [ [ first ] dip first <=> ] sort ; inline ] map [ [ first ] dip first <=> ] sort ; inline
: fuel-callers-xref ( word -- ) : fuel-callers-xref ( word -- )

View File

@ -203,7 +203,7 @@ IN: google-tech-talk
{ $code "13 <circle> tell-me" } { $code "13 <circle> tell-me" }
{ $code "103 76 <rectangle> tell-me" } { $code "103 76 <rectangle> tell-me" }
{ $code "101 tell-me" } { $code "101 tell-me" }
{ { $link integer } ", " { $link array } ", and others area built-in classes" } { { $link integer } ", " { $link array } ", and others are built-in classes" }
} }
{ $slide "Object system" { $slide "Object system"
"Anyone can define new shapes..." "Anyone can define new shapes..."

View File

@ -58,7 +58,8 @@ C-cC-eC-r is the same as C-cC-er)).
- M-. : edit word at point in Emacs - M-. : edit word at point in Emacs
- M-TAB : complete word at point - M-TAB : complete word at point
- C-cC-ev : edit vocabulary (M-x fuel-edit-vocabulary) - C-cC-ev : edit vocabulary (M-x fuel-edit-vocabulary)
- C-cC-ew : edit word (M-x fuel-edit-word) - C-cC-ew : edit word (M-x fuel-edit-word-at-point)
- C-cC-ed : edit word's doc (M-x fuel-edit-word-at-point)
- C-cr, C-cC-er : eval region - C-cr, C-cC-er : eval region
- C-M-r, C-cC-ee : eval region, extending it to definition boundaries - C-M-r, C-cC-ee : eval region, extending it to definition boundaries
@ -78,6 +79,7 @@ C-cC-eC-r is the same as C-cC-er)).
- TAB : complete word at point - TAB : complete word at point
- M-. : edit word at point in Emacs - M-. : edit word at point in Emacs
- C-ca : toggle autodoc mode - C-ca : toggle autodoc mode
- C-cs : toggle stack mode
- C-cv : edit vocabulary - C-cv : edit vocabulary
- C-ch : help for word at point - C-ch : help for word at point
- C-ck : run file - C-ck : run file
@ -96,5 +98,10 @@ C-cC-eC-r is the same as C-cC-er)).
- SPC/S-SPC : scroll up/down - SPC/S-SPC : scroll up/down
- TAB/S-TAB : next/previous headline - TAB/S-TAB : next/previous headline
- C-cz : switch to listener - C-cz : switch to listener
- q: bury buffer - q : bury buffer
* In crossref buffers
- TAB/BACKTAB : navigate links
- RET/mouse click : follow link
- q : bury buffer

View File

@ -24,8 +24,9 @@
;;; Customization: ;;; Customization:
(defgroup factor-mode nil (defgroup factor-mode nil
"Major mode for Factor source code" "Major mode for Factor source code."
:group 'fuel) :group 'fuel
:group 'languages)
(defcustom factor-mode-use-fuel t (defcustom factor-mode-use-fuel t
"Whether to use the full FUEL facilities in factor mode. "Whether to use the full FUEL facilities in factor mode.

View File

@ -22,7 +22,7 @@
;;; Customization: ;;; Customization:
(defgroup fuel-autodoc nil (defgroup fuel-autodoc nil
"Options controlling FUEL's autodoc system" "Options controlling FUEL's autodoc system."
:group 'fuel) :group 'fuel)
(defcustom fuel-autodoc-minibuffer-font-lock t (defcustom fuel-autodoc-minibuffer-font-lock t

View File

@ -25,8 +25,8 @@
;;;###autoload ;;;###autoload
(defgroup fuel nil (defgroup fuel nil
"Factor's Ultimate Emacs Library" "Factor's Ultimate Emacs Library."
:group 'language) :group 'languages)
;;; Emacs compatibility: ;;; Emacs compatibility:
@ -74,12 +74,14 @@
len)) len))
(defsubst fuel--region-to-string (begin &optional end) (defsubst fuel--region-to-string (begin &optional end)
(let ((end (or end (point))))
(if (< begin end)
(mapconcat 'identity (mapconcat 'identity
(split-string (buffer-substring-no-properties begin (split-string (buffer-substring-no-properties begin end)
(or end (point)))
nil nil
t) t)
" ")) " ")
"")))
(defsubst empty-string-p (str) (equal str "")) (defsubst empty-string-p (str) (equal str ""))

View File

@ -134,7 +134,7 @@
(defconst fuel-con--prompt-regex "( .+ ) ") (defconst fuel-con--prompt-regex "( .+ ) ")
(defconst fuel-con--eot-marker "<~FUEL~>") (defconst fuel-con--eot-marker "<~FUEL~>")
(defconst fuel-con--init-stanza "USE: fuel f fuel-eval") (defconst fuel-con--init-stanza "USE: fuel fuel-retort")
(defconst fuel-con--comint-finished-regex (defconst fuel-con--comint-finished-regex
(format "^%s$" fuel-con--eot-marker)) (format "^%s$" fuel-con--eot-marker))

View File

@ -14,29 +14,30 @@
;;; Code: ;;; Code:
(require 'fuel-base)
(require 'fuel-eval) (require 'fuel-eval)
(require 'fuel-popup)
(require 'fuel-font-lock) (require 'fuel-font-lock)
(require 'fuel-base)
;;; Customization: ;;; Customization:
(defgroup fuel-debug nil (defgroup fuel-debug nil
"Major mode for interaction with the Factor debugger" "Major mode for interaction with the Factor debugger."
:group 'fuel) :group 'fuel)
(defcustom fuel-debug-mode-hook nil (defcustom fuel-debug-mode-hook nil
"Hook run after `fuel-debug-mode' activates" "Hook run after `fuel-debug-mode' activates."
:group 'fuel-debug :group 'fuel-debug
:type 'hook) :type 'hook)
(defcustom fuel-debug-show-short-help t (defcustom fuel-debug-show-short-help t
"Whether to show short help on available keys in debugger" "Whether to show short help on available keys in debugger."
:group 'fuel-debug :group 'fuel-debug
:type 'boolean) :type 'boolean)
(fuel-font-lock--define-faces (fuel-font-lock--define-faces
fuel-debug-font-lock font-lock fuel-debug fuel-font-lock-debug font-lock fuel-debug
((error warning "highlighting errors") ((error warning "highlighting errors")
(line variable-name "line numbers in errors/warnings") (line variable-name "line numbers in errors/warnings")
(column variable-name "column numbers in errors/warnings") (column variable-name "column numbers in errors/warnings")
@ -66,14 +67,14 @@
(defconst fuel-debug--restart-regex "^:\\([0-9]+\\) \\(.+\\)") (defconst fuel-debug--restart-regex "^:\\([0-9]+\\) \\(.+\\)")
(defconst fuel-debug--font-lock-keywords (defconst fuel-debug--font-lock-keywords
`((,fuel-debug--error-file-regex . 'fuel-debug-font-lock-error) `((,fuel-debug--error-file-regex . 'fuel-font-lock-debug-error)
(,fuel-debug--error-line-regex 1 'fuel-debug-font-lock-line) (,fuel-debug--error-line-regex 1 'fuel-font-lock-debug-line)
(,fuel-debug--error-cont-regex 1 'fuel-debug-font-lock-column) (,fuel-debug--error-cont-regex 1 'fuel-font-lock-debug-column)
(,fuel-debug--restart-regex (1 'fuel-debug-font-lock-restart-number) (,fuel-debug--restart-regex (1 'fuel-font-lock-debug-restart-number)
(2 'fuel-debug-font-lock-restart-name)) (2 'fuel-font-lock-debug-restart-name))
(,fuel-debug--compiler-info-regex 1 'fuel-debug-font-lock-restart-number) (,fuel-debug--compiler-info-regex 1 'fuel-font-lock-debug-restart-number)
("^\\(Restarts?\\|Loading\\) .+$" . 'fuel-debug-font-lock-info) ("^\\(Restarts?\\|Loading\\) .+$" . 'fuel-font-lock-debug-info)
("^Error: " . 'fuel-debug-font-lock-error))) ("^Error: " . 'fuel-font-lock-debug-error)))
(defun fuel-debug--font-lock-setup () (defun fuel-debug--font-lock-setup ()
(set (make-local-variable 'font-lock-defaults) (set (make-local-variable 'font-lock-defaults)
@ -82,7 +83,8 @@
;;; Debug buffer: ;;; Debug buffer:
(defvar fuel-debug--buffer nil) (fuel-popup--define fuel-debug--buffer
"*fuel debug*" 'fuel-debug-mode)
(make-variable-buffer-local (make-variable-buffer-local
(defvar fuel-debug--last-ret nil)) (defvar fuel-debug--last-ret nil))
@ -90,13 +92,6 @@
(make-variable-buffer-local (make-variable-buffer-local
(defvar fuel-debug--file nil)) (defvar fuel-debug--file nil))
(defun fuel-debug--buffer ()
(or (and (buffer-live-p fuel-debug--buffer) fuel-debug--buffer)
(with-current-buffer
(setq fuel-debug--buffer (get-buffer-create "*fuel dbg*"))
(fuel-debug-mode)
(current-buffer))))
(defun fuel-debug--display-retort (ret &optional success-msg no-pop file) (defun fuel-debug--display-retort (ret &optional success-msg no-pop file)
(let ((err (fuel-eval--retort-error ret)) (let ((err (fuel-eval--retort-error ret))
(inhibit-read-only t)) (inhibit-read-only t))
@ -111,16 +106,16 @@
(when err (when err
(fuel-debug--display-restarts err) (fuel-debug--display-restarts err)
(delete-blank-lines) (delete-blank-lines)
(newline) (newline))
(let ((hstr (fuel-debug--help-string err file))) (let ((hstr (fuel-debug--help-string err file)))
(if fuel-debug-show-short-help (if fuel-debug-show-short-help
(insert "-----------\n" hstr "\n") (insert "-----------\n" hstr "\n")
(message "%s" hstr)))) (message "%s" hstr)))
(setq fuel-debug--last-ret ret) (setq fuel-debug--last-ret ret)
(setq fuel-debug--file file) (setq fuel-debug--file file)
(goto-char (point-max)) (goto-char (point-max))
(font-lock-fontify-buffer) (font-lock-fontify-buffer)
(when (and err (not no-pop)) (pop-to-buffer fuel-debug--buffer)) (when (and err (not no-pop)) (fuel-popup--display))
(not err)))) (not err))))
(defun fuel-debug--display-output (ret) (defun fuel-debug--display-output (ret)
@ -179,16 +174,16 @@
(defun fuel-debug-goto-error () (defun fuel-debug-goto-error ()
(interactive) (interactive)
(let* ((err (or (fuel-debug--buffer-error) (let* ((err (fuel-debug--buffer-error))
(error "No errors reported")))
(file (or (fuel-debug--buffer-file) (file (or (fuel-debug--buffer-file)
(error "No file associated with error"))) (error "No file associated with compilation")))
(l/c (fuel-eval--error-line/column err)) (l/c (and err (fuel-eval--error-line/column err)))
(line (or (car l/c) 1)) (line (or (car l/c) 1))
(col (or (cdr l/c) 0))) (col (or (cdr l/c) 0)))
(find-file-other-window file) (find-file-other-window file)
(when line
(goto-line line) (goto-line line)
(forward-char col))) (when col (forward-char col)))))
(defun fuel-debug--read-restart-no () (defun fuel-debug--read-restart-no ()
(let ((rs (fuel-debug--buffer-restarts))) (let ((rs (fuel-debug--buffer-restarts)))
@ -224,9 +219,11 @@
(unless (re-search-forward (format "^%s" info) nil t) (unless (re-search-forward (format "^%s" info) nil t)
(error "%s information not available" info)) (error "%s information not available" info))
(message "Retrieving %s info ..." info) (message "Retrieving %s info ..." info)
(unless (fuel-debug--display-retort (unless (fuel-debug--display-retort (fuel-eval--send/wait
(fuel-eval--send/wait `(:fuel ((:factor ,info)))) `(:fuel ((:factor ,info))))
"" (fuel-debug--buffer-file)) ""
nil
(fuel-debug--buffer-file))
(error "Sorry, no %s info available" info)))) (error "Sorry, no %s info available" info))))

View File

@ -21,13 +21,24 @@
;;; Faces: ;;; Faces:
(defmacro fuel-font-lock--make-face (prefix def-prefix group face def doc) (defgroup fuel-faces nil
(let ((face (intern (format "%s-%s" prefix face))) "Faces used by FUEL."
(def (intern (format "%s-%s-face" def-prefix def)))) :group 'fuel
:group 'faces)
(defmacro fuel-font-lock--defface (face def group doc)
`(defface ,face (face-default-spec ,def) `(defface ,face (face-default-spec ,def)
,(format "Face for %s." doc) ,(format "Face for %s." doc)
:group ',group :group ',group
:group 'faces))) :group 'fuel-faces
:group 'faces))
(put 'fuel-font-lock--defface 'lisp-indent-function 1)
(defmacro fuel-font-lock--make-face (prefix def-prefix group face def doc)
(let ((face (intern (format "%s-%s" prefix face)))
(def (intern (format "%s-%s-face" def-prefix def))))
`(fuel-font-lock--defface ,face ,def ,group ,doc)))
(defmacro fuel-font-lock--define-faces (prefix def-prefix group faces) (defmacro fuel-font-lock--define-faces (prefix def-prefix group faces)
(let ((setup (make-symbol (format "%s--faces-setup" prefix)))) (let ((setup (make-symbol (format "%s--faces-setup" prefix))))

View File

@ -18,13 +18,14 @@
(require 'fuel-autodoc) (require 'fuel-autodoc)
(require 'fuel-completion) (require 'fuel-completion)
(require 'fuel-font-lock) (require 'fuel-font-lock)
(require 'fuel-popup)
(require 'fuel-base) (require 'fuel-base)
;;; Customization: ;;; Customization:
(defgroup fuel-help nil (defgroup fuel-help nil
"Options controlling FUEL's help system" "Options controlling FUEL's help system."
:group 'fuel) :group 'fuel)
(defcustom fuel-help-always-ask t (defcustom fuel-help-always-ask t
@ -47,10 +48,8 @@
:type 'integer :type 'integer
:group 'fuel-help) :group 'fuel-help)
(defface fuel-help-font-lock-headlines '((t (:bold t :weight bold))) (fuel-font-lock--defface fuel-font-lock-help-headlines
"Face for headlines in help buffers." 'bold fuel-hep "headlines in help buffers")
:group 'fuel-help
:group 'faces)
;;; Help browser history: ;;; Help browser history:
@ -81,10 +80,9 @@
;;; Fuel help buffer and internals: ;;; Fuel help buffer and internals:
(defun fuel-help--help-buffer () (fuel-popup--define fuel-help--buffer
(with-current-buffer (get-buffer-create "*fuel help*") "*fuel help*" 'fuel-help-mode)
(fuel-help-mode)
(current-buffer)))
(defvar fuel-help--prompt-history nil) (defvar fuel-help--prompt-history nil)
@ -111,7 +109,7 @@
(fuel-help--insert-contents def out)))) (fuel-help--insert-contents def out))))
(defun fuel-help--insert-contents (def str &optional nopush) (defun fuel-help--insert-contents (def str &optional nopush)
(let ((hb (fuel-help--help-buffer)) (let ((hb (fuel-help--buffer))
(inhibit-read-only t) (inhibit-read-only t)
(font-lock-verbose nil)) (font-lock-verbose nil))
(set-buffer hb) (set-buffer hb)
@ -124,7 +122,7 @@
(kill-region (point-min) (point)) (kill-region (point-min) (point))
(fuel-help--history-push (cons def (buffer-string))))) (fuel-help--history-push (cons def (buffer-string)))))
(set-buffer-modified-p nil) (set-buffer-modified-p nil)
(pop-to-buffer hb) (fuel-popup--display)
(goto-char (point-min)) (goto-char (point-min))
(message "%s" def))) (message "%s" def)))
@ -154,7 +152,7 @@
(defconst fuel-help--font-lock-keywords (defconst fuel-help--font-lock-keywords
`(,@fuel-font-lock--font-lock-keywords `(,@fuel-font-lock--font-lock-keywords
(,fuel-help--headlines-regexp . 'fuel-help-font-lock-headlines))) (,fuel-help--headlines-regexp . 'fuel-font-lock-help-headlines)))
@ -211,7 +209,6 @@ buffer."
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(suppress-keymap map) (suppress-keymap map)
(define-key map "\C-m" 'fuel-help) (define-key map "\C-m" 'fuel-help)
(define-key map "q" 'bury-buffer)
(define-key map "b" 'fuel-help-previous) (define-key map "b" 'fuel-help-previous)
(define-key map "f" 'fuel-help-next) (define-key map "f" 'fuel-help-next)
(define-key map "l" 'fuel-help-previous) (define-key map "l" 'fuel-help-previous)
@ -222,6 +219,7 @@ buffer."
(define-key map [(backtab)] 'fuel-help-previous-headline) (define-key map [(backtab)] 'fuel-help-previous-headline)
(define-key map (kbd "SPC") 'scroll-up) (define-key map (kbd "SPC") 'scroll-up)
(define-key map (kbd "S-SPC") 'scroll-down) (define-key map (kbd "S-SPC") 'scroll-down)
(define-key map "\M-." 'fuel-edit-word-at-point)
(define-key map "\C-cz" 'run-factor) (define-key map "\C-cz" 'run-factor)
(define-key map "\C-c\C-z" 'run-factor) (define-key map "\C-c\C-z" 'run-factor)
map)) map))
@ -245,6 +243,7 @@ buffer."
(fuel-autodoc-mode) (fuel-autodoc-mode)
(run-mode-hooks 'fuel-help-mode-hook) (run-mode-hooks 'fuel-help-mode-hook)
(setq buffer-read-only t)) (setq buffer-read-only t))

View File

@ -13,8 +13,9 @@
;;; Code: ;;; Code:
(require 'fuel-eval) (require 'fuel-stack)
(require 'fuel-completion) (require 'fuel-completion)
(require 'fuel-eval)
(require 'fuel-connection) (require 'fuel-connection)
(require 'fuel-syntax) (require 'fuel-syntax)
(require 'fuel-base) (require 'fuel-base)
@ -25,7 +26,7 @@
;;; Customization: ;;; Customization:
(defgroup fuel-listener nil (defgroup fuel-listener nil
"Interacting with a Factor listener inside Emacs" "Interacting with a Factor listener inside Emacs."
:group 'fuel) :group 'fuel)
(defcustom fuel-listener-factor-binary "~/factor/factor" (defcustom fuel-listener-factor-binary "~/factor/factor"
@ -102,16 +103,9 @@ buffer."
(goto-char (point-max)) (goto-char (point-max))
(unless seen (error "No prompt found!")))) (unless seen (error "No prompt found!"))))
(defun fuel-listener-nuke ()
;;; Completion support (interactive)
(fuel-con--setup-connection fuel-listener--buffer))
(defsubst fuel-listener--current-vocab () nil)
(defsubst fuel-listener--usings () nil)
(defun fuel-listener--setup-completion ()
(setq fuel-syntax--current-vocab-function 'fuel-listener--current-vocab)
(setq fuel-syntax--usings-function 'fuel-listener--usings)
(set-syntax-table fuel-syntax--syntax-table))
;;; Interface: starting fuel listener ;;; Interface: starting fuel listener
@ -128,6 +122,28 @@ buffer."
(pop-to-buffer buf) (pop-to-buffer buf)
(switch-to-buffer buf)))) (switch-to-buffer buf))))
;;; Completion support
(defsubst fuel-listener--current-vocab () nil)
(defsubst fuel-listener--usings () nil)
(defun fuel-listener--setup-completion ()
(setq fuel-syntax--current-vocab-function 'fuel-listener--current-vocab)
(setq fuel-syntax--usings-function 'fuel-listener--usings)
(set-syntax-table fuel-syntax--syntax-table))
;;; Stack mode support
(defun fuel-listener--stack-region ()
(fuel--region-to-string (if (zerop (fuel-syntax--brackets-depth))
(comint-line-beginning-position)
(1+ (fuel-syntax--brackets-start)))))
(defun fuel-listener--setup-stack-mode ()
(setq fuel-stack--region-function 'fuel-listener--stack-region))
;;; Fuel listener mode: ;;; Fuel listener mode:
@ -138,12 +154,15 @@ buffer."
(set (make-local-variable 'comint-prompt-regexp) fuel-con--prompt-regex) (set (make-local-variable 'comint-prompt-regexp) fuel-con--prompt-regex)
(set (make-local-variable 'comint-use-prompt-regexp) t) (set (make-local-variable 'comint-use-prompt-regexp) t)
(set (make-local-variable 'comint-prompt-read-only) t) (set (make-local-variable 'comint-prompt-read-only) t)
(fuel-listener--setup-completion)) (set-syntax-table fuel-syntax--syntax-table)
(fuel-listener--setup-completion)
(fuel-listener--setup-stack-mode))
(define-key fuel-listener-mode-map "\C-cz" 'run-factor) (define-key fuel-listener-mode-map "\C-cz" 'run-factor)
(define-key fuel-listener-mode-map "\C-c\C-z" 'run-factor) (define-key fuel-listener-mode-map "\C-c\C-z" 'run-factor)
(define-key fuel-listener-mode-map "\C-ca" 'fuel-autodoc-mode) (define-key fuel-listener-mode-map "\C-ca" 'fuel-autodoc-mode)
(define-key fuel-listener-mode-map "\C-ch" 'fuel-help) (define-key fuel-listener-mode-map "\C-ch" 'fuel-help)
(define-key fuel-listener-mode-map "\C-cs" 'fuel-stack-mode)
(define-key fuel-listener-mode-map "\M-." 'fuel-edit-word-at-point) (define-key fuel-listener-mode-map "\M-." 'fuel-edit-word-at-point)
(define-key fuel-listener-mode-map "\C-cv" 'fuel-edit-vocabulary) (define-key fuel-listener-mode-map "\C-cv" 'fuel-edit-vocabulary)
(define-key fuel-listener-mode-map "\C-c\C-v" 'fuel-edit-vocabulary) (define-key fuel-listener-mode-map "\C-c\C-v" 'fuel-edit-vocabulary)

View File

@ -136,11 +136,27 @@ With prefix, asks for the word to edit."
(interactive "P") (interactive "P")
(let* ((word (or (and (not arg) (fuel-syntax-symbol-at-point)) (let* ((word (or (and (not arg) (fuel-syntax-symbol-at-point))
(fuel-completion--read-word "Edit word: "))) (fuel-completion--read-word "Edit word: ")))
(cmd `(:fuel ((:quote ,word) fuel-get-edit-location)))) (cmd `(:fuel* ((:quote ,word) fuel-get-edit-location))))
(condition-case nil (condition-case nil
(fuel--try-edit (fuel-eval--send/wait cmd)) (fuel--try-edit (fuel-eval--send/wait cmd))
(error (fuel-edit-vocabulary nil word))))) (error (fuel-edit-vocabulary nil word)))))
(defun fuel-edit-word-doc-at-point (&optional arg)
"Opens a new window visiting the documentation file for the word at point.
With prefix, asks for the word to edit."
(interactive "P")
(let* ((word (or (and (not arg) (fuel-syntax-symbol-at-point))
(fuel-completion--read-word "Edit word: ")))
(cmd `(:fuel* ((:quote ,word) fuel-get-doc-location))))
(condition-case nil
(fuel--try-edit (fuel-eval--send/wait cmd))
(error (when (y-or-n-p (concat "No documentation found. "
"Do you want to open the vocab's "
"doc file? "))
(find-file-other-window
(format "%s-docs.factor"
(file-name-sans-extension (buffer-file-name)))))))))
(defvar fuel-mode--word-history nil) (defvar fuel-mode--word-history nil)
(defun fuel-edit-word (&optional arg) (defun fuel-edit-word (&optional arg)
@ -152,7 +168,7 @@ offered."
nil nil
fuel-mode--word-history fuel-mode--word-history
arg)) arg))
(cmd `(:fuel ((:quote ,word) fuel-get-edit-location)))) (cmd `(:fuel* ((:quote ,word) fuel-get-edit-location))))
(fuel--try-edit (fuel-eval--send/wait cmd)))) (fuel--try-edit (fuel-eval--send/wait cmd))))
(defvar fuel--vocabs-prompt-history nil) (defvar fuel--vocabs-prompt-history nil)
@ -183,8 +199,7 @@ With prefix argument, ask for word."
(fuel-syntax-symbol-at-point)))) (fuel-syntax-symbol-at-point))))
(when word (when word
(message "Looking up %s's callers ..." word) (message "Looking up %s's callers ..." word)
(fuel-xref--show-callers word) (fuel-xref--show-callers word))))
(message ""))))
(defun fuel-show-callees (&optional arg) (defun fuel-show-callees (&optional arg)
"Show a list of callers of word at point. "Show a list of callers of word at point.
@ -196,8 +211,7 @@ With prefix argument, ask for word."
(fuel-syntax-symbol-at-point)))) (fuel-syntax-symbol-at-point))))
(when word (when word
(message "Looking up %s's callees ..." word) (message "Looking up %s's callees ..." word)
(fuel-xref--show-callees word) (fuel-xref--show-callees word))))
(message ""))))
;;; Minor mode definition: ;;; Minor mode definition:
@ -252,6 +266,7 @@ interacting with a factor listener is at your disposal.
(define-key fuel-mode-map "\C-c\M->" 'fuel-show-callees) (define-key fuel-mode-map "\C-c\M->" 'fuel-show-callees)
(define-key fuel-mode-map (kbd "M-TAB") 'fuel-completion--complete-symbol) (define-key fuel-mode-map (kbd "M-TAB") 'fuel-completion--complete-symbol)
(fuel-mode--key ?e ?d 'fuel-edit-word-doc-at-point)
(fuel-mode--key ?e ?e 'fuel-eval-extended-region) (fuel-mode--key ?e ?e 'fuel-eval-extended-region)
(fuel-mode--key ?e ?l 'fuel-run-file) (fuel-mode--key ?e ?l 'fuel-run-file)
(fuel-mode--key ?e ?r 'fuel-eval-region) (fuel-mode--key ?e ?r 'fuel-eval-region)

60
misc/fuel/fuel-popup.el Normal file
View File

@ -0,0 +1,60 @@
;;; fuel-popup.el -- popup windows
;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
;; See http://factorcode.org/license.txt for BSD license.
;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
;; Keywords: languages, fuel, factor
;; Start date: Sun Dec 21, 2008 14:37
;;; Comentary:
;; A minor mode to pop up windows and restore configurations
;; afterwards.
;;; Code:
(make-variable-buffer-local
(defvar fuel-popup--created-window nil))
(make-variable-buffer-local
(defvar fuel-popup--selected-window nil))
(defun fuel-popup--display (&optional buffer)
(when buffer (set-buffer buffer))
(let ((selected-window (selected-window))
(buffer (current-buffer)))
(unless (eq selected-window (get-buffer-window buffer))
(let ((windows))
(walk-windows (lambda (w) (push w windows)) nil t)
(prog1 (pop-to-buffer buffer)
(set (make-local-variable 'fuel-popup--created-window)
(unless (memq (selected-window) windows) (selected-window)))
(set (make-local-variable 'fuel-popup--selected-window)
selected-window))))))
(defun fuel-popup--quit ()
(interactive)
(let ((selected fuel-popup--selected-window)
(created fuel-popup--created-window))
(bury-buffer)
(when (eq created (selected-window)) (delete-window created))
(when (window-live-p selected) (select-window selected))))
(define-minor-mode fuel-popup-mode
"Mode for displaying read only stuff"
nil nil
'(("q" . fuel-popup--quit)))
(defmacro fuel-popup--define (fun name mode)
`(defun ,fun ()
(or (get-buffer ,name)
(with-current-buffer (get-buffer-create ,name)
(funcall ,mode)
(fuel-popup-mode)
(current-buffer)))))
(put 'fuel-popup--define 'lisp-indent-function 1)
(provide 'fuel-popup)
;;; fuel-popup.el ends here

View File

@ -17,21 +17,20 @@
(require 'fuel-autodoc) (require 'fuel-autodoc)
(require 'fuel-syntax) (require 'fuel-syntax)
(require 'fuel-eval) (require 'fuel-eval)
(require 'fuel-font-lock)
(require 'fuel-base) (require 'fuel-base)
;;; Customization ;;; Customization
(defgroup fuel-stack nil (defgroup fuel-stack nil
"Customization for FUEL's stack inference engine" "Customization for FUEL's stack inference engine."
:group 'fuel) :group 'fuel)
(defface fuel-font-lock-stack-region (face-user-default-spec 'highlight) (fuel-font-lock--defface fuel-font-lock-stack-region
"Face used to highlight the region whose stack effect is shown" 'highlight fuel-stack "highlighting the stack effect region")
:group 'fuel-stack
:group 'faces)
(defcustom fuel-stack-highlight-period 2 (defcustom fuel-stack-highlight-period 2.0
"Time, in seconds, the region is highlighted when showing its "Time, in seconds, the region is highlighted when showing its
stack effect. stack effect.
@ -97,13 +96,20 @@ With prefix argument, use current region instead"
(defvar fuel-stack-mode-string " S" (defvar fuel-stack-mode-string " S"
"Modeline indicator for fuel-stack-mode")) "Modeline indicator for fuel-stack-mode"))
(make-variable-buffer-local
(defvar fuel-stack--region-function
'(lambda ()
(fuel--region-to-string (1+ (fuel-syntax--beginning-of-sexp-pos))))))
(defun fuel-stack--eldoc () (defun fuel-stack--eldoc ()
(when (looking-at-p " \\|$") (when (looking-at-p " \\|$")
(let* ((r (fuel--region-to-string (1+ (fuel-syntax--beginning-of-sexp-pos)))) (let* ((r (funcall fuel-stack--region-function))
(e (fuel-stack--infer-effect/prop r))) (e (and r
(not (string-match "^ *$" r))
(fuel-stack--infer-effect/prop r))))
(when e (when e
(if fuel-stack-mode-show-sexp-p (if fuel-stack-mode-show-sexp-p
(concat (fuel--shorten-str r 30) ": " e) (concat (fuel--shorten-str r 30) " -> " e)
e))))) e)))))
(define-minor-mode fuel-stack-mode (define-minor-mode fuel-stack-mode

View File

@ -277,6 +277,11 @@
(defsubst fuel-syntax--end-of-defun () (defsubst fuel-syntax--end-of-defun ()
(re-search-forward fuel-syntax--end-of-def-regex nil t)) (re-search-forward fuel-syntax--end-of-def-regex nil t))
(defsubst fuel-syntax--end-of-defun-pos ()
(save-excursion
(re-search-forward fuel-syntax--end-of-def-regex nil t)
(point)))
(defconst fuel-syntax--defun-signature-regex (defconst fuel-syntax--defun-signature-regex
(format "\\(%s\\|%s\\)" (format "\\(%s\\|%s\\)"
(format ":[^ ]* [^ ]+\\(%s\\)*" fuel-syntax--stack-effect-regex) (format ":[^ ]* [^ ]+\\(%s\\)*" fuel-syntax--stack-effect-regex)

View File

@ -13,6 +13,10 @@
;;; Code: ;;; Code:
(require 'fuel-eval)
(require 'fuel-syntax)
(require 'fuel-popup)
(require 'fuel-font-lock)
(require 'fuel-base) (require 'fuel-base)
(require 'button) (require 'button)
@ -24,13 +28,25 @@
"FUEL's cross-referencing engine." "FUEL's cross-referencing engine."
:group 'fuel) :group 'fuel)
(defcustom fuel-xref-follow-link-to-word-p t
"Whether, when following a link to a caller, we position the
cursor at the first ocurrence of the used word."
:group 'fuel-xref
:type 'boolean)
(fuel-font-lock--defface fuel-font-lock-xref-link
'link fuel-xref "highlighting links in cross-reference buffers")
(fuel-font-lock--defface fuel-font-lock-xref-vocab
'italic fuel-xref "vocabulary names in cross-reference buffers")
;;; Buttons: ;;; Buttons:
(define-button-type 'fuel-xref--button-type (define-button-type 'fuel-xref--button-type
'action 'fuel-xref--follow-link 'action 'fuel-xref--follow-link
'follow-link t 'follow-link t
'face 'default) 'face 'fuel-font-lock-xref-link)
(defun fuel-xref--follow-link (button) (defun fuel-xref--follow-link (button)
(let ((file (button-get button 'file)) (let ((file (button-get button 'file))
@ -39,60 +55,81 @@
(error "No file for this ref")) (error "No file for this ref"))
(when (not (file-readable-p file)) (when (not (file-readable-p file))
(error "File '%s' is not readable" file)) (error "File '%s' is not readable" file))
(let ((word fuel-xref--word))
(find-file-other-window file) (find-file-other-window file)
(when (numberp line) (goto-line line)))) (when (numberp line) (goto-line line))
(when (and word fuel-xref-follow-link-to-word-p)
(and (search-forward word
(fuel-syntax--end-of-defun-pos)
t)
(goto-char (match-beginning 0)))))))
;;; The xref buffer: ;;; The xref buffer:
(defvar fuel-xref--buffer-name "*fuel xref*") (fuel-popup--define fuel-xref--buffer
"*fuel xref*" 'fuel-xref-mode)
(defun fuel-xref--get-buffer () (make-local-variable (defvar fuel-xref--word nil))
(let ((buffer (get-buffer fuel-xref--buffer-name)))
(or (and (buffer-live-p buffer) buffer)
(prog1
(set-buffer (get-buffer-create fuel-xref--buffer-name))
(fuel-xref-mode)))))
(defvar fuel-xref--help-string "(Press RET or click to follow crossrefs)") (defvar fuel-xref--help-string "(Press RET or click to follow crossrefs)")
(defun fuel-xref--fill-buffer (title refs) (defun fuel-xref--title (word cc count)
(let ((inhibit-read-only t)) (let ((cc (if cc "using" "used by")))
(with-current-buffer (fuel-xref--get-buffer) (put-text-property 0 (length word) 'font-lock-face 'bold word)
(erase-buffer) (cond ((zerop count) (format "No known words %s %s" cc word))
(insert title "\n\n") ((= 1 count) (format "1 word %s %s:" cc word))
(dolist (ref refs) (t (format "%s words %s %s:" count cc word)))))
(when (and (first ref) (second ref) (numberp (third ref)))
(defun fuel-xref--insert-ref (ref)
(when (and (stringp (first ref))
(stringp (third ref))
(numberp (fourth ref)))
(insert " ") (insert " ")
(insert-text-button (first ref) (insert-text-button (first ref)
:type 'fuel-xref--button-type :type 'fuel-xref--button-type
'help-echo (format "File: %s (%s)" 'help-echo (format "File: %s (%s)"
(second ref) (third ref)
(third ref)) (fourth ref))
'file (second ref) 'file (third ref)
'line (third ref)) 'line (fourth ref))
(newline))) (when (stringp (second ref))
(when refs (insert (format " (in %s)" (second ref))))
(insert "\n\n" fuel-xref--help-string "\n")) (newline)
(goto-char (point-min))))) t))
(defun fuel-xref--fill-buffer (word cc refs)
(let ((inhibit-read-only t)
(count 0))
(with-current-buffer (fuel-xref--buffer)
(erase-buffer)
(dolist (ref refs)
(when (fuel-xref--insert-ref ref) (setq count (1+ count))))
(goto-char (point-min))
(insert (fuel-xref--title word cc count) "\n\n")
(when (> count 0)
(setq fuel-xref--word (and cc word))
(goto-char (point-max))
(insert "\n" fuel-xref--help-string "\n"))
(goto-char (point-min))
count)))
(defun fuel-xref--fill-and-display (word cc refs)
(let ((count (fuel-xref--fill-buffer word cc refs)))
(if (zerop count)
(error (fuel-xref--title word cc 0))
(message "")
(fuel-popup--display (fuel-xref--buffer)))))
(defun fuel-xref--show-callers (word) (defun fuel-xref--show-callers (word)
(let* ((cmd `(:fuel* (((:quote ,word) fuel-callers-xref)))) (let* ((cmd `(:fuel* (((:quote ,word) fuel-callers-xref))))
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))) (res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
(title (format (if res "Callers of '%s':" (fuel-xref--fill-and-display word t res)))
"No callers found for '%s'")
word)))
(fuel-xref--fill-buffer title res)
(pop-to-buffer (fuel-xref--get-buffer))))
(defun fuel-xref--show-callees (word) (defun fuel-xref--show-callees (word)
(let* ((cmd `(:fuel* (((:quote ,word) fuel-callees-xref)))) (let* ((cmd `(:fuel* (((:quote ,word) fuel-callees-xref))))
(res (fuel-eval--retort-result (fuel-eval--send/wait cmd))) (res (fuel-eval--retort-result (fuel-eval--send/wait cmd))))
(title (format (if res "Words called by '%s':" (fuel-xref--fill-and-display word nil res)))
"No callees found for '%s'")
word)))
(fuel-xref--fill-buffer title res)
(pop-to-buffer (fuel-xref--get-buffer))))
;;; Xref mode: ;;; Xref mode:
@ -113,7 +150,7 @@
(use-local-map fuel-xref-mode-map) (use-local-map fuel-xref-mode-map)
(setq mode-name "FUEL Xref") (setq mode-name "FUEL Xref")
(setq major-mode 'fuel-xref-mode) (setq major-mode 'fuel-xref-mode)
(fuel-font-lock--font-lock-setup) (font-lock-add-keywords nil '(("(in \\(.+\\))" 1 'fuel-font-lock-xref-vocab)))
(setq buffer-read-only t)) (setq buffer-read-only t))