about summary refs log blame commit diff stats
path: root/src/main.nim
blob: 9d782a9062b07f99751187aa25ea4bed0f0ca776 (plain) (tree)
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
Console

   (X) #0   09/12/06  console commands
   (X) #1   09/12/06  quick find
   (X) #2   09/12/06  open with
   (X) #4   09/12/06  history for console
   (X) #13  09/12/27  display docstring of a command


General

   (X) #5   09/12/06  move code from fm into objects
   (X) #6   09/12/06  move main to __init__
   (X) #7   09/12/06  cooler titlebar
   (X) #8   09/12/17  Add operations to modify files/directories
   (X) #9   09/12/24  add a widget for managing running operations
   (X) #10  09/12/24  sorting
   (X) #11  09/12/27  filter
   (X) #12  09/12/27  jump through the list in a specific order
   (X) #14  09/12/29  make filelists inherit from pagers
   (X) #15  09/12/29  better way of running processes!!~
   (X) #16  10/01/01  list of bookmarks
   (X) #21  10/01/01  write help!
   (X) #22  10/01/03  add getopt options to change flags/mode
   (X) #29  10/01/06  add chmod command
   (X) #30  10/01/06  add a way to create symlinks
   (X) #32  10/01/08  place the (hidden) cursor to a meaningful position
   (X) #34  10/01/09  display free disk space
   (X) #35  10/01/09  display disk usage of files in current directory
   ( ) #36  10/01/11  help coloring is terribly inefficient
   (X) #37  10/01/13  better tab completion for OpenConsole
   ( ) #38  10/01/16  searching in pager
   (X) #39  10/01/17  flushinput not always good
   (X) #42  10/01/17  memorize directory for `` when using :cd
   (X) #43  10/01/18  internally treat the bookmarks ` and ' the same
   ( ) #44  10/01/18  more error messages :P
   (X) #47  10/01/19  less restricive auto preview
   (X) #48  10/01/19  abbreviate commands with first unambiguous substring
   ( ) #50  10/01/19  add more unit tests
   ( ) #51  10/01/21  remove directory.marked_items ?
   (X) #55  10/01/24  allow change of filename when pasting
          you're given the choice between overwriting or appending a "_"
   ( ) #56  10/01/30  warn before deleting mount points
   ( ) #57  10/01/30  warn before deleting unseen marked files
   (X) #58  10/02/04  change the title of the terminal
   (X) #61  10/02/09  show sum of size of marked files
   (X) #63  10/02/15  limit filesize in previews
   ( ) #64  10/02/25  scroll in previews
   (X) #66  10/02/28  explain how colorschemes work
   ( ) #70  10/03/14  mouse handler for titlebar
   ( ) #71  10/03/21  previews: black/whitelist + read file


Bugs

   (X) #17  10/01/01  why do bookmarks disappear sometimes?
   (X) #18  10/01/01  fix notify widget (by adding a LogView?)
   (X) #19  10/01/01  resizing after pressing g
   (X) #23  10/01/04  stop dir loading with ^C -> wont load anymore
   (X) #25  10/01/06  directories sometimes dont reload correctly
   (X) #26  10/01/06  :delete on symlinks of directories fails
   (X) #31  10/01/06  ^C breaks cd-after-exit by stopping sourced shell script
   (X) #40  10/01/17  freeze with unavailable sshfs
          Not rangers fault (?)
   (X) #41  10/01/17  capital file extensions are not recognized
   (X) #46  10/01/19  old username displayed after using su
   (X) #49  10/01/19  fix unit tests :'(
   (X) #52  10/01/23  special characters in tab completion
   (X) #54  10/01/23  max_dirsize_for_autopreview not working
   ( ) #60  10/02/05  utf support improvable
   (X) #62  10/02/15  curs_set can raise an exception
   (X) #65  10/02/16  "source ranger ranger some/file.txt" shouldn't cd after exit
   (X) #67  10/03/08  terminal title in tty
   (X) #69  10/03/11  tab-completion breaks with Apps subclass
   (X) #73  10/03/21  when clicking on the first column, it goes 1x down
   (X) #74  10/03/21  console doesn't scroll


Ideas

   ( ) #20  10/01/01  use inotify to monitor filesystem changes
   ( ) #24  10/01/06  progress bar
   (X) #27  10/01/06  hide bookmarks in list which contain hidden dir
   (X) #28  10/01/06  use regexp instead of string for searching
   ( ) #33  10/01/08  accelerate mousewheel speed
   ( ) #45  10/01/18  hooks for events like setting changes
   ( ) #53  10/01/23  merge fm and environment
   ( ) #68  10/03/10  threads, to seperate ui and loading
   ( ) #72  10/03/21  ranger daemon which does the slow io tasks
   ( ) #75  10/03/28  navigate in history
   ( ) #76  10/03/28  save history between sessions
ptato <nincsnevem662@gmail.com> 2023-09-06 00:12:02 +0200 main: remove stray eprint, update -o info text' href='/ahoang/chawan/commit/src/main.nim?id=257fa69d7e06bd0a6f22dd0394ad5fab1527dad0'>257fa69d ^
6efa1869 ^


26e8968a ^
4e0fd8c7 ^
6efa1869 ^


ededd738 ^
6efa1869 ^























ededd738 ^
6efa1869 ^




ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^


ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^






ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^

ededd738 ^
6efa1869 ^




ededd738 ^
6efa1869 ^
1b153725 ^

6efa1869 ^












































ededd738 ^
0b46fc3a ^
6efa1869 ^












302e6cd0 ^
6efa1869 ^










e5a0fd6a ^





6efa1869 ^
9318ad33 ^
6efa1869 ^






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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

              
                        
                           
 

                  
 
                     
                    
                   
                      
                   
                
                     
                   
 
                       
 

                                  
 





                                                   
 

                           
 

                                           
                                                                         
                                                                          

                                                        
                                                                               


                                                         
                                                        
                                                              


                                                         
 























                               
 




                            
 

                                  
 


                        
 

                                                 
 

                    
 

                             
 






                                                   
 

                           
 

                                                                     
 

                  
 

                             
 

                         
 

                  
 




                                                                   
 
                      

              












































                                                                           
                     
         












                                                             
         










                                                  





                                                                     
 
                                  






                                          
import version

import server/forkserver
let forks = newForkServer()

import std/options
import std/os

import config/chapath
import config/config
import display/term
import io/serversocket
import local/client
import types/opt
import utils/strwidth
import utils/twtstr

import chagashi/charset

proc main() =
  let params = commandLineParams()

  proc version(long: static bool = false): string =
    result = "Chawan browser v0.1 "
    when defined(debug):
      result &= "(debug)"
    else:
      result &= "(release)"

  proc help(i: int) =
    let s = version() & """

Usage: cha [options] [URL(s) or file(s)...]
Options:
    --                          Interpret all following arguments as URLs
    -c, --css <stylesheet>      Pass stylesheet (e.g. -c 'a{color: blue}')
    -d, --dump                  Print page to stdout
    -h, --help                  Print this usage message
    -o, --opt <config>          Pass config options (e.g. -o 'page.q="quit()"')
    -r, --run <script/file>     Run passed script or file
    -v, --version               Print version information
    -C, --config <file>         Override config path
    -I, --input-charset <enc>   Specify document charset
    -M, --monochrome            Set color-mode to 'monochrome'
    -O, --display-charset <enc> Specify display charset
    -T, --type <type>           Specify content mime type
    -V, --visual                Visual startup mode"""

    if i == 0:
      stdout.write(s & '\n')
    else:
      stderr.write(s & '\n')
    quit(i)

  var ctype = none(string)
  var cs = CHARSET_UNKNOWN
  var pages: seq[string]
  var dump = false
  var visual = false
  var escape_all = false
  var opts: seq[string]
  var stylesheet = ""
  var configPath = none(string)

  var i = 0
  while i < params.len:
    let param = params[i]

    if escape_all: # after --
      pages.add(param)
      inc i
      continue

    proc getnext(): string =
      inc i
      if i < params.len:
        return params[i]
      help(1)

    proc pconfig() =
      configPath = some(getnext())

    proc pversion() =
      echo version(true)
      quit(0)

    proc pmonochrome() =
      opts.add("display.color-mode = monochrome")

    proc pvisual() =
      visual = true

    proc ptype() =
      ctype = some(getnext())

    proc pgetCharset(): Charset =
      let s = getnext()
      let cs = getCharset(s)
      if cs == CHARSET_UNKNOWN:
        stderr.write("Unknown charset " & s & "\n")
        quit(1)
      return cs

    proc pinput_charset() =
      cs = pgetCharset()

    proc poutput_charset() =
      opts.add("encoding.display-charset = '" & $pgetCharset() & "'")

    proc pdump() =
      dump = true

    proc pcss() =
      stylesheet &= getnext()

    proc popt() =
      opts.add(getnext())

    proc phelp() =
      help(0)

    proc prun() =
      let script = dqEscape(getnext())
      opts.add("start.startup-script = \"\"\"" & script & "\"\"\"")
      opts.add("start.headless = true")
      dump = true

    if param.len == 0:
      inc i
      continue

    const NeedsNextParam = {'C', 'I', 'O', 'T', 'c', 'o', 'r'}

    if param[0] == '-':
      if param.len == 1:
        # If param == "-", i.e. it is a single dash, then ignore it.
        # (Some programs use single-dash to read from stdin, but we do that
        # automatically when stdin is not a tty. So ignoring it entirely
        # is probably for the best.)
        inc i
        continue
      if param[1] != '-':
        for j in 1 ..< param.len:
          if j != param.high and param[j] in NeedsNextParam:
            # expecting next parameter, but not the last char...
            help(1)
          case param[j]
          of 'C': pconfig()
          of 'I': pinput_charset()
          of 'M': pmonochrome()
          of 'O': poutput_charset()
          of 'T': ptype()
          of 'V': pvisual()
          of 'c': pcss()
          of 'd': pdump()
          of 'h': phelp()
          of 'o': popt()
          of 'r': prun()
          of 'v': pversion()
          else: help(1)
      else:
        case param
        of "--config": pconfig()
        of "--input-charset": pinput_charset()
        of "--monochrome": pmonochrome()
        of "--output-charset": poutput_charset()
        of "--type": ptype()
        of "--visual": pvisual()
        of "--css": pcss()
        of "--dump": pdump()
        of "--help": phelp()
        of "--opt": popt()
        of "--run": prun()
        of "--version": pversion()
        of "--": escape_all = true
        else: help(1)
    else:
      pages.add(param)
    inc i

  let config = readConfig(configPath)
  for opt in opts:
    config.parseConfig(getCurrentDir(), opt, laxnames = true)
  config.css.stylesheet &= stylesheet

  set_cjk_ambiguous(config.display.double_width_ambiguous)

  if pages.len == 0 and stdin.isatty():
    if visual:
      pages.add(config.start.visual_home)
    else:
      let http = getEnv("HTTP_HOME")
      if http != "": pages.add(http)
      else:
        let www = getEnv("WWW_HOME")
        if www != "": pages.add(www)

  if pages.len == 0 and not config.start.headless:
    if stdin.isatty:
      help(1)

  forks.loadForkServerConfig(config)
  let tmpdir0 = config.external.tmpdir.unquote()
  if tmpdir0.isErr:
    stderr.write("Error unquoting external.tmpdir: " & tmpdir0.error)
    stderr.write("Exiting...")
    quit(1)
  SocketDirectory = tmpdir0.get

  let c = newClient(config, forks)
  try:
    c.launchClient(pages, ctype, cs, dump)
  except CatchableError:
    c.flushConsole()
    raise

main()