atlas-engineer / nyxt

Nyxt - the hacker's browser.
https://nyxt-browser.com/
9.88k stars 413 forks source link

A question about workflow #195

Closed sivark closed 5 years ago

sivark commented 5 years ago

Thanks for a very interesting browser concept!

This is more in the spirit of a workflow question, and possibly feature requests, rather than an issue. Feel free to redirect to a more appropriate place.


I seek more control and deliberation in the way I interact with the information I'm accessing through my browser. As a start, I would like to manage my tabs programmatically (by performing operations based on their content). Here are some scenarios I'm envisioning...

I desire an interface where I can create solutions like these on the fly. Conceptually, this might involve:

  1. A good data structure to represent the contents (and any metadata) of each tab.
  2. A collection of tabs stored in an iterable data structure. Probably a list of lists i.e. leaves of a tree. A browser window can simply point to specific locations on this collection. (This formulation would be amenable to the possibility of multiple windows or frames, etc.)
  3. The equivalent of a filter function to traverse the iterable, and filter tabs using a user-defined function (maybe a lambda)
  4. A map function. Produce the URL or title of every tab. Maybe reload/refresh an iterable of tabs every hour. Maybe one could use this to eg: implement a tiny ad-hoc crawler (Given a collection of pages, collect the links in each page, filter them by some criteria, then open those links in new tabs, and do all this three levels deep)
  5. Given that I mentioned filter and map, what about reduce? I can't currently think of a particularly useful way to reduce a collection of tabs beyond just concatenating their HTML content.
  6. Export/import this iterable.
  7. Access to a library ecosystem which will provide useful functions like parsing HTML, processing strings (eg: fuzzy search, or mis-spelled words, or non-dictionary words to collect proper nouns), etc. Eg: If I could access a table from Wikipedia and convert it into the lisp equivalent of a dataframe, then I can start doing my own data analysis on the fly ;-)

So, is this compatible with the vision for Next? Are you formulating the solution in a different mental framework? Are some of these things already possible? If so, please help me get started :-) Cheers!

Ambrevar commented 5 years ago

Thanks back!

Long story short: yes, this is very much the mindset of Next!

Some of those ideas are already possible, at least from the REPL. The user interface is still at a very early stage of development however, so for now not much of it is possible without significant work on the Lisp side.

Note that in Next terminology, "tabs" are "buffers" :)

Some things I'd like to see implemented, hopefully not to far in the future:

In the end, anything that's exposed to the Lisp core is programmable, and only your imagination is the limit!

  1. A good data structure to represent the contents (and any metadata) of each tab.

HTML header information is a bit lacking at the moment I think. We can add more metadata (such as access time) to the BUFFER class.

  1. A collection of tabs stored in an iterable data structure. Probably a list of lists i.e. leaves of a tree. A browser window can simply point to specific locations on this collection. (This formulation would be amenable to the possibility of multiple windows or frames, etc.)

Buffers are already stored as a list in the BUFFERS slot in the REMOTE-INTERFACE class. Not sure we would need a tree though. I think subdividing buffers into groups can be done at a different level of abstraction.

We already have multiple-window support. I did not understand what you meant with "point to specific locations on this collection."

  1. The equivalent of a filter function to traverse the iterable, and filter tabs using a user-defined function (maybe a lambda)

As mentioned above, we will have some very powerful fuzzy-search features, including filtering by content (HTML body) and modes.

Instead of user-defined filters, I'm thinking that user-defined sources would be more generic. See Emacs Helm-mini for a good example of this.

  1. A map function. Produce the URL or title of every tab. Maybe reload/refresh an iterable of tabs every hour. Maybe one could use this to eg: implement a tiny ad-hoc crawler (Given a collection of pages, collect the links in each page, filter them by some criteria, then open those links in new tabs, and do all this three levels deep)

All this is already doable: you can use the Common Lisp map, mapcar and friends over (buffer *interface*) and do what you want! :)

  1. Given that I mentioned filter and map, what about reduce? I can't currently think of a particularly useful way to reduce a collection of tabs beyond just concatenating their HTML content.

Yup, same, can't think of anything but buffer concatenation, and that alone is an interesting idea! :D

  1. Export/import this iterable.

You mean the resulting Common Lisp function? This is already doable: write a bunch of higher-order-functions in your ~/.config/next/init.lisp, and define the desired command in there. Is this what you meant?

  1. Access to a library ecosystem which will provide useful functions like parsing HTML, processing strings (eg: fuzzy search, or mis-spelled words, or non-dictionary words to collect proper nouns), etc. Eg: If I could access a table from Wikipedia and convert it into the lisp equivalent of a dataframe, then I can start doing my own data analysis on the fly ;-)

Good news: All the Common Lisp eco-system is available to you! DOM and string manipulation, etc. there is so much out there!

If so, please help me get started :-)

You can start reading the above article I've sent you. If you are serious about hacking with Next, you'll need some knowledge of Common Lisp (if you know Emacs, you already know a useful bunch). I think a good starting point to get started with the Lisp core source is the buffer.lisp file. Documentation is still lacking, we are working on it!

Note that these weeks we have been rewriting a big chunk of the API, so expect some important changes in the Next release.

Thanks for the extensive feedback!

sivark commented 5 years ago

Thanks for the prompt response and useful suggestions.

In the end, anything that's exposed to the Lisp core is programmable, and only your imagination is the limit!

I like the sound of this!

Some of those ideas are already possible, at least from the REPL. The user interface is still at a very early stage of development however, so for now not much of it is possible without significant work on the Lisp side.

You can start reading the above article I've sent you. If you are serious about hacking with Next, you'll need some knowledge of Common Lisp (if you know Emacs, you already know a useful bunch). I think a good starting point to get started with the Lisp core source is the buffer.lisp file.

I haven't really programmed with Common Lisp or used Emacs much, but I've played around a little with Racket, so I'm absolutely happy to get my hands dirty with Lisp in a REPL, and start learning.

Concretely, IIUC: To access the BUFFER class and the BUFFERS slot in the REMOTE-INTERFACE class in a REPL, I need to set up Emacs with Slime, based on https://next.atlas.engineer/documentation#slime-with-a-compiled-version-of-next

  1. That would enable reading BUFFER state via REMOTE-INTERFACE. I can then import any Common Lisp library into the REPL to use it to process the data.
  2. Once I have the results I want (eg: list of buffers to close, or links to open, or whatever), I can write via the REMOTE-INTERFACE to update the state in the browser.

So, I tried following the manual, to connect to the swank server using slime (I'm actually using the common-lisp layer in spacemacs, since I'm kinda new to Emacs). I'm using the compiled version of Next browser available on AUR.

I can start a swank server from Next (verified by looking at the console output of next --verbose), but I'm not able to connect to it from slime. Here's the error message I see in Emacs:

SWANK/BACKEND:SLDB-BREAK-ON-RETURN not implemented
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [ABORT] Return to sldb level 2.
 1: [ABORT] Return to sldb level 1.
 2: [*ABORT] Return to SLIME's top level.
 3: [ABORT] abort thread (#<THREAD "worker" RUNNING {10061FB523}>)

Backtrace:
  0: (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0)
  1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0) #<NULL-LEXENV>)
  2: (EVAL (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0))
  3: (SWANK:EVAL-FOR-EMACS (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0) "COMMON-LISP-USER" 4)
  4: (SWANK::SLDB-LOOP 2)
  5: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT :IN "/var/cache/pacman/pkg/next-browser-git9193/next-browser-git/src/next-browser/quicklisp/dists/quicklisp/software/slime-v2.23/swank/sbcl.lisp") ..
  6: (SWANK::DEBUG-IN-EMACS #<SIMPLE-ERROR "~S not implemented" {10066D8FF3}>)
  7: (SWANK:INVOKE-SLIME-DEBUGGER #<SIMPLE-ERROR "~S not implemented" {10066D8FF3}>)
  8: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK:SWANK-DEBUGGER-HOOK) {10066D947B}>)
  9: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/var/cache/pacman/pkg/next-browser-git9193/next-browser-git/src/next-browser/quicklisp/dists/quicklisp/software/slime-v2.23/swank/sbcl.lisp") #<FUNCTI..
 10: (SWANK:SWANK-DEBUGGER-HOOK #<SIMPLE-ERROR "~S not implemented" {10066D8FF3}> #<unused argument>)
 11: (SB-DEBUG::RUN-HOOK *DEBUGGER-HOOK* #<SIMPLE-ERROR "~S not implemented" {10066D8FF3}>)
 12: (INVOKE-DEBUGGER #<SIMPLE-ERROR "~S not implemented" {10066D8FF3}>)
 13: (ERROR "~S not implemented" SWANK/BACKEND:SLDB-BREAK-ON-RETURN)
 14: (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0)
 15: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0) #<NULL-LEXENV>)
 16: (EVAL (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0))
 17: (SWANK:EVAL-FOR-EMACS (SWANK/BACKEND:SLDB-BREAK-ON-RETURN 0) "COMMON-LISP-USER" 3)
 18: (SWANK::SLDB-LOOP 1)
 19: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT :IN "/var/cache/pacman/pkg/next-browser-git9193/next-browser-git/src/next-browser/quicklisp/dists/quicklisp/software/slime-v2.23/swank/sbcl.lisp") ..
 20: (SWANK::DEBUG-IN-EMACS #<SIMPLE-ERROR "Can't locate module: ~s" {100635EC03}>)
 21: (SWANK:INVOKE-SLIME-DEBUGGER #<SIMPLE-ERROR "Can't locate module: ~s" {100635EC03}>)
 22: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK:SWANK-DEBUGGER-HOOK) {100635F18B}>)
 23: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/var/cache/pacman/pkg/next-browser-git9193/next-browser-git/src/next-browser/quicklisp/dists/quicklisp/software/slime-v2.23/swank/sbcl.lisp") #<FUNCTI..
 24: (SWANK:SWANK-DEBUGGER-HOOK #<SIMPLE-ERROR "Can't locate module: ~s" {100635EC03}> #<unused argument>)
 25: (SB-DEBUG::RUN-HOOK *DEBUGGER-HOOK* #<SIMPLE-ERROR "Can't locate module: ~s" {100635EC03}>)
 26: (INVOKE-DEBUGGER #<SIMPLE-ERROR "Can't locate module: ~s" {100635EC03}>)
 27: (ERROR "Can't locate module: ~s" SWANK-IO-PACKAGE::SWANK-INDENTATION)
 28: (SWANK::MODULE-FILENAME SWANK-IO-PACKAGE::SWANK-INDENTATION)
 29: (SWANK:SWANK-REQUIRE (SWANK-IO-PACKAGE::SWANK-SBCL-EXTS SWANK-IO-PACKAGE::SWANK-INDENTATION SWANK-IO-PACKAGE::SWANK-TRACE-DIALOG SWANK-IO-PACKAGE::SWANK-PACKAGE-FU SWANK-IO-PACKAGE::SWANK-PRESENTATION..
 30: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK:SWANK-REQUIRE (QUOTE (SWANK-IO-PACKAGE::SWANK-SBCL-EXTS SWANK-IO-PACKAGE::SWANK-INDENTATION SWANK-IO-PACKAGE::SWANK-TRACE-DIALOG SWANK-IO-PACKAGE::SWANK-PACKAGE-FU..
 31: (EVAL (SWANK:SWANK-REQUIRE (QUOTE (SWANK-IO-PACKAGE::SWANK-SBCL-EXTS SWANK-IO-PACKAGE::SWANK-INDENTATION SWANK-IO-PACKAGE::SWANK-TRACE-DIALOG SWANK-IO-PACKAGE::SWANK-PACKAGE-FU SWANK-IO-PACKAGE::SWANK..
 32: (SWANK:EVAL-FOR-EMACS (SWANK:SWANK-REQUIRE (QUOTE (SWANK-IO-PACKAGE::SWANK-SBCL-EXTS SWANK-IO-PACKAGE::SWANK-INDENTATION SWANK-IO-PACKAGE::SWANK-TRACE-DIALOG SWANK-IO-PACKAGE::SWANK-PACKAGE-FU SWANK-I..
 33: ((LAMBDA NIL :IN SWANK::SPAWN-WORKER-THREAD))
 34: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<FUNCTION (LAMBDA NIL :IN SWANK::SPAWN-WORKER-THREAD) {522BD16B}>)
 35: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/var/cache/pacman/pkg/next-browser-git9193/next-browser-git/src/next-browser/quicklisp/dists/quicklisp/software/slime-v2.23/swank/sbcl.lisp") #<FUNCTI..
 36: ((LAMBDA NIL :IN SWANK::SPAWN-WORKER-THREAD))
 37: ((FLET SB-UNIX::BODY :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 38: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 39: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 40: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX))
 41: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7F4884356D6B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
 42: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "worker" RUNNING {10061FB523}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK::SPAWN-WORKER-THREAD) {10061FB4CB}> NIL)
 43: ("foreign function: call_into_lisp")
 44: ("foreign function: new_thread_trampoline")

Superficially (to me), this looks like a previously reported & solved issue but the version of Next I'm using is from after that issue was solved.

I could share the output of the slime-events buffer if need be.

Ambrevar commented 5 years ago

Great to see you getting started!

And yes, you understood correctly! ;)

Regarding your issue, please report

The backtrace shows that SLDB cannot be invoked properly, so there is mostly likely an issue with your SLIME installation, or with the AUR package.

You could try the following:

sivark commented 5 years ago

Thanks for that suggestion @Ambrevar !

I managed to get the Slime/Swank connection working by running Next from source (still using spacemacs, so that doesn't seem to be a dealbreaker, for anyone who comes across this later). So it's probably something with the AUR package being dated. Thanks for that suggestion.

Now for the fun stuff! (in case another Lisp/Next newbie comes across this in the future, this is a demonstration that the connection works and we can access the tabs from Slime)

;; "Sourcing" the contents of the module
(in-package :next)

;; *interface* is an instance of REMOTE-INTERFACE
;; Whose buffers slot is a hash map of buffers
;; This will print the respective URL of each buffer
(maphash (lambda (k v)
                 (print (cons k (name v))))
                 (buffers *interface*))
  • Fuzzy-search by URL, Title, metadata (with some tag system) and content. That's right, we could filter buffers by words found in their body.

Would this be by executing js in each buffer (using parenscript), or by getting the contents of the buffer and processing it in lisp?


Basic question: I can start next from the SBCL shell, but running the same commands as a script seems to fail. Any idea why this might be the case?

~> cat start-next.lisp
#!/usr/bin/sbcl --script

;; Execute this in sbcl

;; For loading from lisp source
(require :asdf)
(asdf:load-asd "/home/username/next-browser/next.asd")

;; Load the Next module
(ql:quickload :next)

;; Start a browser window
(next:start)

;; Start Swank server
;; (in-package :next)
;; (start-swank)

~> ./start-next.lisp
While evaluating the form starting at line 4, column 0
  of #P" /home/username/next-browser/next.asd":
Unhandled MISSING-DEPENDENCY in thread #<SB-THREAD:THREAD "main thread" RUNNING {10005205B3}>: Component "trivial-features" not found, required by NIL

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005205B3}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK Component "trivial-features" not found, required by NIL #<unused argument> :QUIT T)
1: (SB-DEBUG::RUN-HOOK SB-EXT:*INVOKE-DEBUGGER-HOOK* Component "trivial-features" not found, required by NIL)
2: (INVOKE-DEBUGGER Component "trivial-features" not found, required by NIL)
3: (ERROR MISSING-DEPENDENCY :REQUIRED-BY NIL :REQUIRES "trivial-features")
4: (ASDF/FIND-COMPONENT:RESOLVE-DEPENDENCY-NAME NIL "trivial-features" NIL)
5: ((LAMBDA NIL :IN ASDF/PARSE-DEFSYSTEM:REGISTER-SYSTEM-DEFINITION))
6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (DEFSYSTEM :NEXT :VERSION "1.2.0" :AUTHOR "Atlas Engineer LLC" :LICENSE "BSD 3-Clause" :SERIAL T :DEFSYSTEM-DEPENDS-ON ("trivial-features") ...) #<NULL-LEXENV>)
7: (SB-EXT:EVAL-TLF (DEFSYSTEM :NEXT :VERSION "1.2.0" :AUTHOR "Atlas Engineer LLC" :LICENSE "BSD 3-Clause" :SERIAL T :DEFSYSTEM-DEPENDS-ON ("trivial-features") ...) 0 NIL)
8: ((LABELS SB-FASL::EVAL-FORM :IN SB-INT:LOAD-AS-SOURCE) (DEFSYSTEM :NEXT :VERSION "1.2.0" :AUTHOR "Atlas Engineer LLC" :LICENSE "BSD 3-Clause" :SERIAL T :DEFSYSTEM-DEPENDS-ON ("trivial-features") ...) 0)
9: ((LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) (DEFSYSTEM :NEXT :VERSION "1.2.0" :AUTHOR "Atlas Engineer LLC" :LICENSE "BSD 3-Clause" :SERIAL T :DEFSYSTEM-DEPENDS-ON ("trivial-features") ...) :CURRENT-INDEX 0)
10: (SB-C::%DO-FORMS-FROM-INFO #<CLOSURE (LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) {1004CCC1EB}> #<SB-C::SOURCE-INFO {1004CCC1A3}> SB-C::INPUT-ERROR-IN-LOAD)
11: (SB-INT:LOAD-AS-SOURCE #<SB-INT:FORM-TRACKING-STREAM for "file /home/username/next-browser/next.asd" {1004CCA323}> :VERBOSE NIL :PRINT NIL :CONTEXT "loading")
12: ((FLET SB-FASL::THUNK :IN LOAD))
13: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<CLOSURE (FLET SB-FASL::THUNK :IN LOAD) {7FE4068ADA8B}> #<SB-INT:FORM-TRACKING-STREAM for "file /home/username/next-browser/next.asd" {1004CCA323}>)
14: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-INT:FORM-TRACKING-STREAM for "file /home/username/next-browser/next.asd" {1004CCA323}> NIL)
15: (LOAD #P"/home/username/next-browser/next.asd" :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :UTF-8)
16: (CALL-WITH-MUFFLED-CONDITIONS #<CLOSURE (LAMBDA NIL :IN LOAD*) {1004CC7BBB}> ("Overwriting already existing readtable ~S." #(#:FINALIZERS-OFF-WARNING :ASDF-FINALIZERS)))
17: ((FLET "THUNK" :IN PERFORM))
18: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #<CLOSURE (FLET "THUNK" :IN PERFORM) {7FE4068ADDDB}>)
19: ((:METHOD PERFORM (DEFINE-OP SYSTEM)) #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next">) [fast-method]
20: ((SB-PCL::EMF PERFORM) #<unused argument> #<unused argument> #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next">)
21: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
22: ((:METHOD PERFORM-WITH-RESTARTS :AROUND (T T)) #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next">) [fast-method]
23: ((:METHOD PERFORM-PLAN (T)) #<SEQUENTIAL-PLAN {1004CC1C03}>) [fast-method]
24: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
25: ((:METHOD PERFORM-PLAN :AROUND (T)) #<SEQUENTIAL-PLAN {1004CC1C03}>) [fast-method]
26: ((:METHOD OPERATE (OPERATION COMPONENT)) #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next"> :PLAN-CLASS NIL :PLAN-OPTIONS NIL) [fast-method]
27: ((SB-PCL::EMF OPERATE) #<unused argument> #<unused argument> #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next">)
28: ((LAMBDA NIL :IN OPERATE))
29: ((:METHOD OPERATE :AROUND (T T)) #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next">) [fast-method]
30: ((LAMBDA NIL :IN FIND-SYSTEM))
31: (ASDF/SESSION:CONSULT-ASDF-CACHE (FIND-SYSTEM "next") #<CLOSURE (LAMBDA NIL :IN FIND-SYSTEM) {1004C2333B}>)
32: ((:METHOD FIND-COMPONENT (STRING T)) "next" (NIL) :REGISTERED NIL) [fast-method]
33: ((:METHOD OPERATE (OPERATION T)) #<DEFINE-OP > ("next")) [fast-method]
34: ((SB-PCL::EMF OPERATE) #<unused argument> #<unused argument> #<DEFINE-OP > ("next"))
35: ((LAMBDA NIL :IN OPERATE))
36: ((:METHOD OPERATE :AROUND (T T)) #<DEFINE-OP > ("next")) [fast-method]
37: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<CLOSURE (LAMBDA NIL :IN OPERATE) {1004C1738B}> :OVERRIDE T :KEY NIL :OVERRIDE-CACHE T :OVERRIDE-FORCING NIL)
38: ((LAMBDA NIL :IN OPERATE))
39: ((:METHOD OPERATE :AROUND (T T)) #<DEFINE-OP > #<ASDF/SYSTEM:UNDEFINED-SYSTEM "next">) [fast-method]
40: ((LAMBDA NIL :IN LOAD-ASD))
41: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<CLOSURE (LAMBDA NIL :IN LOAD-ASD) {1002FCBE4B}> :OVERRIDE NIL :KEY NIL :OVERRIDE-CACHE NIL :OVERRIDE-FORCING NIL)
42: (SB-INT:SIMPLE-EVAL-IN-LEXENV (LOAD-ASD "/home/username/next-browser/next.asd") #<NULL-LEXENV>)
43: (SB-EXT:EVAL-TLF (LOAD-ASD "/home/username/next-browser/next.asd") 1 NIL)
44: ((LABELS SB-FASL::EVAL-FORM :IN SB-INT:LOAD-AS-SOURCE) (LOAD-ASD "/home/username/next-browser/next.asd") 1)
45: ((LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) (LOAD-ASD "/home/username/next-browser/next.asd") :CURRENT-INDEX 1)
46: (SB-C::%DO-FORMS-FROM-INFO #<CLOSURE (LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) {10018784CB}> #<SB-C::SOURCE-INFO {1001878483}> SB-C::INPUT-ERROR-IN-LOAD)
47: (SB-INT:LOAD-AS-SOURCE #<SB-SYS:FD-STREAM for "file /home/username/start-next.lisp" {100186E8C3}> :VERBOSE NIL :PRINT NIL :CONTEXT "loading")
48: ((FLET SB-FASL::THUNK :IN LOAD))
49: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<CLOSURE (FLET SB-FASL::THUNK :IN LOAD) {7FE4068AF69B}> #<SB-SYS:FD-STREAM for "file /home/username/start-next.lisp" {100186E8C3}>)
50: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-SYS:FD-STREAM for "file /home/username/start-next.lisp" {100186E8C3}> NIL)
51: (LOAD #<SB-SYS:FD-STREAM for "file /home/username/start-next.lisp" {100186E8C3}> :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :DEFAULT)
52: ((FLET SB-IMPL::LOAD-SCRIPT :IN SB-IMPL::PROCESS-SCRIPT) #<SB-SYS:FD-STREAM for "file /home/username/start-next.lisp" {100186E8C3}>)
53: ((FLET SB-UNIX::BODY :IN SB-IMPL::PROCESS-SCRIPT))
54: ((FLET "WITHOUT-INTERRUPTS-BODY-2" :IN SB-IMPL::PROCESS-SCRIPT))
55: (SB-IMPL::PROCESS-SCRIPT "./start-next.lisp")
56: (SB-IMPL::TOPLEVEL-INIT)
57: ((FLET SB-UNIX::BODY :IN SB-EXT:SAVE-LISP-AND-DIE))
58: ((FLET "WITHOUT-INTERRUPTS-BODY-14" :IN SB-EXT:SAVE-LISP-AND-DIE))
59: ((LABELS SB-IMPL::RESTART-LISP :IN SB-EXT:SAVE-LISP-AND-DIE))

unhandled condition in --disable-debugger mode, quitting
; 
; compilation unit aborted
;   caught 1 fatal ERROR condition
Ambrevar commented 5 years ago

Thanks for the feedback!

I'm not very familiar with SBCL scripts, but I guess something as simple as adding

(load "~/.sbclrc")

before loading next.asd would be enough.

That said, you should not need this script at all. It's easier to simply generate a binary and run it.

Using the distributed Makefile, you can run

make next

(Run make for more documentation.)

Or, if you want to do it manually in your favourite Lisp environment:

(asdf:make :next)

should work.

-- Pierre Neidhardt https://ambrevar.xyz/

alexherbo2 commented 5 years ago

@Ambrevar How modes would work?

Ambrevar commented 5 years ago

Modes are a work-in-progress and for now they are simply classes with key bindings and some specific slots. I have been thinking quite a lot about what a mode could do and I hope to implement it in the near future. More discussions coming ;)

bijang commented 4 years ago

I use a combo of tree style tab extension https://github.com/piroor/treestyletab and tab session manager https://github.com/sienori/Tab-Session-Manager on Firefox. A great combo, almost perfect. Question is Can tab/buffers be kept tree style, maybe an org tree... a tree of tabs will behave like a visual browsing history, helps to show the thinking behind how you got from one to the other sometimes. Also, I am running tab session manager, to save the sessiond and relevant meta data, on Firefox,... but on different laptops,... currently 3, and synchronising the saved sessions in a shared repository, so potentially I could open a session(s) on a different computer. So my question is, can the same be done, maybe through a cloud or a git repo, and could the name or indentifier of the computer on which the sesssion was saved be optionally included in session metadata, to sort the different sessions, not just by time and place?

Ambrevar commented 4 years ago

Thanks for the suggestions, some good ideas in there!

The tree view of buffers is probably an easy one: it should be enough to add a parent field to the buffer class and store the buffer there. Then we can easily reconstruct the trees by looping over all the buffers. Some buffers can get detached from their parents if it gets deleted, but that's OK I guess.

Regarding the session synchronization: Yes you can synchronize ~/.local/share/next/session.lisp via git and use it on different instance. To identify the various sessions, I suggest that we add the option to include arbitrary fields, e.g. the user can include a (identifier "my-hostname") pair.