about summary refs log tree commit diff stats
path: root/dwm.png
blob: b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 c0 00 00 00 50 08 02 00 00 00 c0 d8 ed .PNG........IHDR.......P........
0020 13 00 00 00 06 62 4b 47 44 00 ff 00 ff 00 ff a0 bd a7 93 00 00 00 09 70 48 59 73 00 00 0b 13 00 .....bKGD..............pHYs.....
0040 00 0b 13 01 00 9a 9c 18 00 00 00 07 74 49 4d 45 07 d6 07 13 0c 31 06 de 1b 2a 10 00 00 00 1d 74 ............tIME.....1...*.....t
0060 45 58 74 43 6f 6d 6d 65 6e 74 00 43 72 65 61 74 65 64 20 77 69 74 68 20 54 68 65 20 47 49 4d 50 EXtComment.Created.with.The.GIMP
0080 ef 64 25 6e 00 00 00 d9 49 44 41 54 78 da ed dd 41 0a 80 30 0c 00 41 23 fe ff cb f1 0d 81 06 52 .d%n....IDATx...A..0..A#.......R
00a0 32 73 56 51 59 da 4b d0 c8 cc 67 92 88 28 1d 3f ed fe b7 79 bd 02 04 84 80 10 10 02 02 01 21 20 2sVQY.K...g..(.?...y..........!.
00c0 04 84 80 40 40 08 08 01 21 20 10 10 02 42 40 08 08 04 84 80 10 10 02 42 40 20 20 04 84 80 10 10 ...@@...!....B@........B@.......
00e0 08 08 01 21 20 04 04 02 a2 43 dc fe 00 d5 ef 03 75 7f 7f a8 7a 7d 2b 10 b6 30 10 10 02 42 40 08 ...!.....C......u...z}+..0...B@.
0100 08 04 84 80 10 10 02 02 01 21 20 04 84 80 40 40 1c f4 55 4f e8 fe 3f d7 b6 79 9a db e7 99 ac 40 .........!....@@..UO..?..y.....@
0120 d8 c2 10 10 02 42 40 20 20 04 84 80 10 10 08 08 01 21 20 04 04 02 42 40 8c 52 9e 07 9a 36 af d3 .....B@..........!....B@.R...6..
0140 7d 3f db e6 93 ac 40 08 08 01 21 20 10 10 02 42 40 08 08 04 84 80 10 10 02 02 01 21 20 04 c4 d5 }?....@...!....B@..........!....
0160 7e 8b c2 15 a9 b3 6f d5 23 00 00 00 00 49 45 4e 44 ae 42 60 82 ~.....o.#....IEND.B`.
a5c064aeb6978928854e74a289702355f00f2'>^
0d52962 ^
8a58888 ^
2ae9cac ^
0d52962 ^
188bbc7 ^
0d52962 ^
2381f7b ^

0d52962 ^

0d52962 ^








0d52962 ^



007b965 ^
0d52962 ^

007b965 ^
0d52962 ^

007b965 ^
0d52962 ^



1bdb931 ^
e2696fc ^
188bbc7 ^
1bdb931 ^
703ed90 ^


1bdb931 ^




95d88a8 ^
1bdb931 ^
1bdb931 ^
3850fba ^
95d88a8 ^
3850fba ^
e2696fc ^
1bdb931 ^


2ae9cac ^
9656e13 ^
69c88da ^
3114176 ^

188bbc7 ^
0d52962 ^
48b7de4 ^
2859063 ^
0d52962 ^


f2299cb ^

0d52962 ^

f98cdd1 ^
188bbc7 ^

f98cdd1 ^
4ad51d6 ^


f98cdd1 ^
188bbc7 ^

5b91af1 ^
2ae9cac ^
5b91af1 ^
0d52962 ^

2ae9cac ^
188bbc7 ^



0d52962 ^







188bbc7 ^




1d3c9f4 ^
44fb3ec ^
188bbc7 ^
0d52962 ^
b95206f ^
188bbc7 ^

0d52962 ^

188bbc7 ^
0d52962 ^

007b965 ^
188bbc7 ^
0d52962 ^
188bbc7 ^
d61b5df ^
0d52962 ^
188bbc7 ^
0d52962 ^

188bbc7 ^




0d52962 ^







188bbc7 ^

0d52962 ^
188bbc7 ^
0d52962 ^
007b965 ^
188bbc7 ^
0d52962 ^
188bbc7 ^

0d52962 ^

188bbc7 ^
e77157d ^
0d52962 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

                                         


                                                                        
                                                                                               
                                                 
                                                           


                                                              
                 
                          
                                     
      
                                                    
     

                                         

                         








                                                                           



                       
                                                                                               

                    
                                                                                               

                    
                                                                                                                                        



                    
                                                                                                            
                                                          
                                                          
            


                                                  




                                                           
                                         
       
                                                   
                              
                                                                                        
                         
                


     
                              
                                          
                       

                                                        
                                               
                               
                                                  
                                                                      


         

                                                                                   

   
                                                        

                                                 
                                                    


               
                                                           

                                                                     
                                            
                                           
                                                                                      

   
                                                  



                                                              







                           




                                                    
                                                                                  
     
                       
                                                                  
                                           

                                                              

                             
                                                                                                                

          
                                                                   
                                                    
                         
                                
                                     
     
                                                                           

   




                                                              







                           

                                                              
                      
                                                               
     
                                                                   
                                                         
                        

                                               

       
                                                                   
                                   
   
-- helpers for selecting portions of text

-- Return any intersection of the region from State.selection1 to
-- State.cursor1 (or current mouse, if mouse is pressed) with the region
-- between {line=line_index, pos=apos} and {line=line_index, pos=bpos}.
-- apos must be less than bpos. However State.selection1 and State.cursor1 can be in any order.
-- Result: positions spos,epos between apos,bpos.
function Text.clip_selection(State, line_index, apos, bpos)
  if State.selection1.line == nil then return nil,nil end
  -- min,max = sorted(State.selection1,State.cursor1)
  local minl,minp = State.selection1.line,State.selection1.pos
  local maxl,maxp
  if State.mouse_down then
    maxl,maxp = Text.mouse_pos(State)
  else
    maxl,maxp = State.cursor1.line,State.cursor1.pos
  end
  if Text.lt1({line=maxl, pos=maxp},
              {line=minl, pos=minp}) then
    minl,maxl = maxl,minl
    minp,maxp = maxp,minp
  end
  -- check if intervals are disjoint
  if line_index < minl then return nil,nil end
  if line_index > maxl then return nil,nil end
  if line_index == minl and bpos <= minp then return nil,nil end
  if line_index == maxl and apos >= maxp then return nil,nil end
  -- compare bounds more carefully (start inclusive, end exclusive)
  local a_ge = Text.le1({line=minl, pos=minp}, {line=line_index, pos=apos})
  local b_lt = Text.lt1({line=line_index, pos=bpos}, {line=maxl, pos=maxp})
  if a_ge and b_lt then
    -- fully contained
    return apos,bpos
  elseif a_ge then
    assert(maxl == line_index, ('maxl %d not equal to line_index %d'):format(maxl, line_index))
    return apos,maxp
  elseif b_lt then
    assert(minl == line_index, ('minl %d not equal to line_index %d'):format(minl, line_index))
    return minp,bpos
  else
    assert(minl == maxl and minl == line_index, ('minl %d, maxl %d and line_index %d are not all equal'):format(minl, maxl, line_index))
    return minp,maxp
  end
end

-- draw highlight for line corresponding to (lo,hi) given an approximate x,y and pos on the same screen line
-- Returns some intermediate computation useful elsewhere.
function Text.draw_highlight(State, line, x,y, pos, lo,hi)
  if lo then
    local lo_offset = Text.offset(line.data, lo)
    local hi_offset = Text.offset(line.data, hi)
    local pos_offset = Text.offset(line.data, pos)
    local lo_px
    if pos == lo then
      lo_px = 0
    else
      local before = line.data:sub(pos_offset, lo_offset-1)
      lo_px = State.font:getWidth(before)
    end
    local s = line.data:sub(lo_offset, hi_offset-1)
    App.color(Highlight_color)
    love.graphics.rectangle('fill', x+lo_px,y, State.font:getWidth(s),State.line_height)
    App.color(Text_color)
    return lo_px
  end
end

function Text.mouse_pos(State)
  local x,y = App.mouse_x(), App.mouse_y()
  if y < State.top then
    return State.screen_top1.line, State.screen_top1.pos
  end
  for line_index,line in ipairs(State.lines) do
    if line.mode == 'text' then
      if Text.in_line(State, line_index, x,y) then
        return line_index, Text.to_pos_on_line(State, line_index, x,y)
      end
    end
  end
  local screen_bottom1 = Text.screen_bottom1(State)
  return screen_bottom1.line, Text.pos_at_end_of_screen_line(State, screen_bottom1)
end

function Text.cut_selection_and_record_undo_event(State)
  if State.selection1.line == nil then return end
  local result = Text.selection(State)
  Text.delete_selection_and_record_undo_event(State)
  return result
end

function Text.delete_selection_and_record_undo_event(State)
  if State.selection1.line == nil then return end
  local minl,maxl = minmax(State.selection1.line, State.cursor1.line)
  local before = snapshot(State, minl, maxl)
  Text.delete_selection_without_undo(State)
  record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
end

function Text.delete_selection_without_undo(State)
  if State.selection1.line == nil then return end
  -- min,max = sorted(State.selection1,State.cursor1)
  local minl,minp = State.selection1.line,State.selection1.pos
  local maxl,maxp = State.cursor1.line,State.cursor1.pos
  if minl > maxl then
    minl,maxl = maxl,minl
    minp,maxp = maxp,minp
  elseif minl == maxl then
    if minp > maxp then
      minp,maxp = maxp,minp
    end
  end
  -- update State.cursor1 and State.selection1
  State.cursor1.line = minl
  State.cursor1.pos = minp
  if Text.lt1(State.cursor1, State.screen_top1) then
    State.screen_top1.line = State.cursor1.line
    State.screen_top1.pos = Text.pos_at_start_of_screen_line(State, State.cursor1)
  end
  State.selection1 = {}
  -- delete everything between min (inclusive) and max (exclusive)
  Text.clear_screen_line_cache(State, minl)
  local min_offset = Text.offset(State.lines[minl].data, minp)
  local max_offset = Text.offset(State.lines[maxl].data, maxp)
  if minl == maxl then
--?     print('minl == maxl')
    State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..State.lines[minl].data:sub(max_offset)
    return
  end
  assert(minl < maxl, ('minl %d not < maxl %d'):format(minl, maxl))
  local rhs = State.lines[maxl].data:sub(max_offset)
  for i=maxl,minl+1,-1 do
    table.remove(State.lines, i)
    table.remove(State.line_cache, i)
  end
  State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..rhs
end

function Text.selection(State)
  if State.selection1.line == nil then return end
  -- min,max = sorted(State.selection1,State.cursor1)
  local minl,minp = State.selection1.line,State.selection1.pos
  local maxl,maxp = State.cursor1.line,State.cursor1.pos
  if minl > maxl then
    minl,maxl = maxl,minl
    minp,maxp = maxp,minp
  elseif minl == maxl then
    if minp > maxp then
      minp,maxp = maxp,minp
    end
  end
  local min_offset = Text.offset(State.lines[minl].data, minp)
  local max_offset = Text.offset(State.lines[maxl].data, maxp)
  if minl == maxl then
    return State.lines[minl].data:sub(min_offset, max_offset-1)
  end
  assert(minl < maxl, ('minl %d not < maxl %d'):format(minl, maxl))
  local result = {State.lines[minl].data:sub(min_offset)}
  for i=minl+1,maxl-1 do
    if State.lines[i].mode == 'text' then
      table.insert(result, State.lines[i].data)
    end
  end
  table.insert(result, State.lines[maxl].data:sub(1, max_offset-1))
  return table.concat(result, '\n')
end