yi-editor / yi

The Haskell-Scriptable Editor
GNU General Public License v2.0
1.51k stars 201 forks source link

Feature Request: Frames #1073

Open rmanne opened 6 years ago

rmanne commented 6 years ago

I'm assuming that "windows" as defined by Yi right now are emacs-style windows and not X11-style windows. (This isn't fully clear to me though, eg: what is the "mini" flag on windows?) However, this means that Yi lacks frames, which is a feature of emacs that I really like.

I believe that once frames are implemented, it will also improve the implementation of a daemon-client setup for Yi. (A proper implementation without race conditions is still blocked on properly allowing concurrent operations in YiM, see #513, but an implementation with infrequent editor action errors should be possible.)

I'm not sure what the implementation should look like right now, but preferably, during the creation of a new frame, we would be able to choose the front-end. Perhaps this would look something like:

newtype FrameRef =
  FrameRef Int

data Editor = Editor
  { refSupply :: !Int
  , bufferStack :: ![BufferRef]
  , buffers :: !(Map BufferRef FBuffer)
  , frames :: !(Map FrameRef Frame)
  , dynamic :: !DynamicState
  , statusLines :: !Statuses
  , maxStatusHeight :: !Int
  , killring :: !KillRing
  , currentRegex :: !(Maybe SearchExp)
  , searchDirection :: !Direction
  , onCloseActions :: !(Map BufferRef (EditorM ()))
  }

-- leave Config unchanged, and use that as a default for new frames (not sure about startActions and initialActions though)

data Frame = Frame
  { frameId :: FrameId
  , tabs :: !(PointedList Tab)
  , pendingEvents :: ![Event]
  }

data FrameConfig = FrameConfig
  { startFrontEnd :: UIBoot
  , configUI :: !UIConfig
  , startActions :: ![Action]
  , initialActions :: ![Action]
  , defaultKm :: !KeymapSet
  , configInputPreprocess :: !(I.P Event Event)
  , debugMode :: !Bool
  , configRegionStyle :: !RegionStyle
  , layoutManagers :: ![AnyLayoutManager]
  }

newFrame :: FrameConfig -> YiM FrameId

(not sure exactly how statusLines works, but it looks like it should belong to the Editor and not the Frame?)

Also, the original design of using "bufferStack" seems puzzling but this is probably a discussion for a different thread. Why not have a "current window" that contains a buffer (which you would then get using bufKey . tabFocus . _focus . tabs_) rather than a "current buffer" (which you get with head . bufferStack)?

noughtmare commented 6 years ago

what is the "mini" flag on windows

Minibuffers are those lines at the bottom of the screen where you can input things like which file you want to open, usually one line tall.

an implementation with infrequent editor action errors should be possible

Can you elaborate on this? What to you mean with editor action errors?

Also, can you indent your code better? It is very hard to read.

rmanne commented 6 years ago

Minibuffers are those lines at the bottom of the screen

Ah, that makes sense.

Can you elaborate on this? What to you mean with editor action errors?

By "editor action errors" I mean that some open/close requests might end up missing. Daemon may request that some file be opened while user input events cause a different file open to be requested. If there are two calls to openNewFile that happen concurrently, are we guaranteed that both files end up opened? I'd assume no given #513, but at the same time, the probability of such a failure is low, since it's hard for a user to make a call to the daemon AND input a key event simultaneously. (Unless ofc, someone makes a client that automates certain actions.)

Indented code in OP.