Fanael / rainbow-delimiters

Emacs rainbow delimiters mode
GNU General Public License v3.0
685 stars 33 forks source link

Screen does not redraw during continuous forward-char or next-line in buffers with many parantheses #16

Closed sprig closed 9 years ago

sprig commented 9 years ago

Hi!

In emacs on OSX, while using rainbow-delimiters-mode, when using the forward-move ing commands (e.g. pressing and holding ctrl+f) but not when using the backwards moving commands, on parts of buffers with many parentheses, emacs does not redraw the screen properly.

What I mean exactly is that the point and highlighted line remain in the same place until the button is released, or until emacs must scroll. When moving backwards/up, this does not occur.

I am using the latest rainbow-delimiters from melpa (20150320...) and emacs version as follows (I think this is the standard version from homebrew):

GNU Emacs 24.4.1 (x86_64-apple-darwin13.4.0, NS apple-appkit-1265.21) of 2014-10-21 on builder10-9.porkrind.org

Fanael commented 9 years ago

I tried to reproduce it on Emacs HEAD and on Emacs 23.1 (both on Windows), to no avail.

Can you link to the file(s) you're seeing this behavior on? Can you run M-x elp-instrument-package RET rainbow-delimiters RET, move for a bit, then M-x elp-results and post the profiling results?

Mine don't show absolutely anything, rainbow-delimiters took a total of 0.03 s in 79 redisplays.

rainbow-delimiters--apply-color        1921        0.0312363999  1.62...e-005
rainbow-delimiters--propertize         79          0.0312363999  0.0003953974
rainbow-delimiters-default-pick-face   1921        0.0155851     8.11...e-006
rainbow-delimiters--char-ineligible-p  2050        0.0           0.0
sprig commented 9 years ago

Thanks for the reply,

Further testing has shown me that this also happens when rainbow-delimiters-mode is off - although it does make the problem worse - so I don't know if you consider this a rainbow-delimiters bug. I will include a chunk of code which is sufficient to reproduce this here, as well as the instrumentation results.

Finally, I want to emphasise that emacs does not slow down: it simply does not redraw the moving cursor.

elp-results:


global-rainbow-delimiters-mode 3 0.067333 0.0224443333 global-rainbow-delimiters-mode-enable-in-buffers 19 0.000605 3.184...e-05 global-rainbow-delimiters-mode-check-buffers 7 0.0001370000 1.957...e-05 global-rainbow-delimiters-mode-cmhh 15 4.9e-05 3.266...e-06


Problem Code

-- module Barcodes
--        ( EndPoint
--        , Bar
--        , BarCode
-- --       , getBarCodesBF
--        ) where

import Data.List as List
import Data.Choose as Choose
import Control.Monad
import System.Random as Random
import Debug.Trace

-- Data

data IntervalEndPoint = MinusInfinity|IntervalValue Float|PlusInfinity deriving (Show, Eq)

data EndPoint = EndPoint { grading :: Int
                         , value :: IntervalEndPoint
                         } deriving (Show, Eq)

data Bar = Bar { leftPt :: EndPoint
               , rightPt :: EndPoint
               } deriving (Show, Eq)

data BarCode = BarCode [Bar] deriving (Show, Eq)

-- Functions

-- Helpers

pairs :: [a] -> [b] -> [(a,b)]
pairs left right =
  [(a,b) | a <- left, b <- right]

elemsOf :: [a] -> [Int] -> [a]
elemsOf elts indices = map (elts !!) indices

-- Barcodes
bars :: [EndPoint] -> [EndPoint] -> [(BarCode, [EndPoint])]
bars leftPts rightPts =
  let rightLen = length rightPts
      leftLen = length leftPts
      rightSelection = choose rightLen leftLen
  in bars_helper leftPts rightPts rightSelection

bars_helper :: [EndPoint] -> [EndPoint] -> Choose -> ([(BarCode, [EndPoint])])
bars_helper leftPts rightPts choice =
  let nextChoice = Choose.next choice
      rightElems = permutations $ elemsOf rightPts $ elems choice
      rightCompl = elemsOf rightPts $ complElems choice
      choiceBarcodes =  [(BarCode $ map (uncurry Bar) $ zip leftPts right_elem, rightCompl)|right_elem <- rightElems]
  in choiceBarcodes ++ maybe [] (bars_helper leftPts rightPts) nextChoice

-- Join barcodes
(<>) :: BarCode -> BarCode -> BarCode
(<>) (BarCode x) (BarCode y) = BarCode (x ++ y)

-- Given a list of (lists of) endpoints (including the infinite ones, ordered by grading), return the list of possible bars one can construct from them
-- This function computes this by brute force
getBarCodesBF :: [[EndPoint]] -> [BarCode]
getBarCodesBF (leastGrade : secondGrade : [] ) = [barcode | (barcode, _) <- bars leastGrade secondGrade]
getBarCodesBF (leastGrade : secondGrade : rest) =
  let leftBarCodes = bars leastGrade secondGrade
      barcodes = [ left_bcode <> right_bcode  | (left_bcode, right_points) <- leftBarCodes, right_bcode <- getBarCodesBF (right_points : rest)]
  in barcodes

main :: IO ()
main = do
  putStrLn "Calculating Barcode!"
  gen <- getStdGen
  let pts = [(map (EndPoint j . IntervalValue) $ take 3 $ randoms gen) | j <- [0..5]]
      barcodes = getBarCodesBF pts
  print barcodes
Fanael commented 9 years ago

Further testing has shown me that this also happens when rainbow-delimiters-mode is off - although it does make the problem worse - so I don't know if you consider this a rainbow-delimiters bug.

Okay, so it may be an Emacs issue.

global-rainbow-delimiters-mode

So you have global-rainbow-delimiters-mode defined in your config. That's not recommended.

Anyway, it's not what I'm interested in. I want a profile of rainbow-delimiters--propertize and its callees, which is where rainbow-delimiters actually does its job. Please call (elp-instrument-package "rainbow-delimiters").

As for the code, unable to reproduce here.

This is Cocoa Emacs, right? If so, can you see if the problem occurs in X11 Emacs? It may be an Emacs's Cocoa display engine bug.

Fanael commented 9 years ago

If so, can you see if the problem occurs in X11 Emacs?

For the record, can't reproduce it here under X11 either. Cocoa engine issue is more and more likely.

sprig commented 9 years ago
rainbow-delimiters--propertize                    10          0.001496      0.0001496
rainbow-delimiters--apply-color                   84          0.0005380000  6.404...e-06
rainbow-delimiters-default-pick-face              84          0.0001909999  2.273...e-06
rainbow-delimiters--char-ineligible-p             112         0.0001009999  9.017...e-07
rainbow-delimiters-mode                           1           8.7e-05       8.7e-05
rainbow-delimiters-mode-set-explicitly            1           2e-06         2e-06
sprig commented 9 years ago

It is indeed in both cocoa emacs and with the railwaycat version (also cocoa). I don't have an X11 version (AFAIK), but will install one tomorrow and report...

sprig commented 9 years ago

Now it appears like Cocoa engine + my configuration - If I start emacs -q and then just load and enable rainbow delimiters, I do not experience this.

Perhaps it is many things working together to slow down redisplay out of which rainbow-delimiters takes x%. I am building X11 emacs as I write this just to be comprehensive (and will report as soon as I'm done), but it now appears that rainbow-delimiters is just a small part of the problem - I'm closing this.

sprig commented 9 years ago

Ok, looks like I spoke too soon - the configure process could not find the required gtk+ lib for building an X11 version (after having installed gtk+ via homebrew), so I'm giving up.