Skip to content

Commit e5c9df1

Browse files
committed
add elixir language server support
1 parent 6e6ff3a commit e5c9df1

File tree

5 files changed

+167
-0
lines changed

5 files changed

+167
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
*~
22
node_modules
33
.DS_Store
4+
_build/
5+
mix.lock
6+
deps/

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ cpan Mojolicious
4444
perl server.pl
4545
```
4646

47+
### Elixir
48+
```elixir
49+
mix deps.get
50+
mix run --no-halt
51+
```
52+
4753
And visit <http://localhost:3000/>. Try opening multiple tabs!
4854

4955
## Changing the port

lib/reacttutorial.ex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
defmodule ReactTutorial do
2+
def version, do: unquote(Mix.Project.config[:version])
3+
def elixir_version, do: unquote(System.version)
4+
5+
use Application
6+
7+
def start( _type, _args ) do
8+
import Supervisor.Spec, warn: false
9+
10+
children = [
11+
worker(__MODULE__, [], function: :run)
12+
]
13+
14+
opts = [strategy: :one_for_one, name: ReactTutorial.Supervisor]
15+
Supervisor.start_link(children, opts)
16+
end
17+
18+
def run do
19+
{ :ok, _ } = Plug.Adapters.Cowboy.http(Server, [], port: 3000)
20+
end
21+
22+
end

lib/server.ex

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
defmodule Server do
2+
import Plug.Conn
3+
4+
def init(options) do
5+
Hex.Shell.info("Server started: http://localhost:3000/")
6+
options
7+
end
8+
9+
def call(conn, _opts) do
10+
http_res(conn, conn.request_path)
11+
end
12+
13+
def http_res(conn, uri) do
14+
cond do
15+
uri =~ ~r"index.html$|^/$|.js$|.css" ->
16+
fileName = get_file_name(uri)
17+
conn
18+
|> put_resp_content_type(get_content_type(conn.request_path))
19+
|> send_resp(200, get_file_content(fileName))
20+
uri == "/api/comments" ->
21+
case conn.method do
22+
"POST" ->
23+
conn = parse(conn)
24+
author = conn.params["author"]
25+
text = conn.params["text"]
26+
id = conn.params["id"]
27+
# Hex.Shell.info("post #{conn.query_string} author:#{author} text:#{text} id:#{id}")
28+
fileName = Path.join(root_path(), "comments.json")
29+
newComment = %{"author" => author, "id" => id, "text" => text}
30+
{:ok, content} = File.read("comments.json")
31+
currentComments = Poison.Parser.parse!(content)
32+
updatedCommentsJson = List.insert_at(currentComments, -1, newComment)
33+
content = Poison.encode!(updatedCommentsJson)
34+
File.write(fileName, content)
35+
conn
36+
|> send_resp(200, "post success")
37+
_ ->
38+
fileName = Path.join(root_path(), "comments.json")
39+
conn
40+
|> put_resp_content_type("application/json")
41+
|> send_resp(200, get_file_content(fileName))
42+
end
43+
true ->
44+
conn
45+
|> send_resp(200, "Hello world")
46+
end
47+
end
48+
49+
def parse(conn, opts \\ []) do
50+
opts = Keyword.put_new(opts, :parsers, [Plug.Parsers.URLENCODED, Plug.Parsers.MULTIPART])
51+
Plug.Parsers.call(conn, Plug.Parsers.init(opts))
52+
end
53+
54+
def get_file_name(uri) do
55+
cond do
56+
uri =~ ~r"index.html$|^/$" ->
57+
Path.join(root_path(), "public/index.html")
58+
uri =~ ~r".js$|.css" ->
59+
Path.join(root_path(), "public" <> uri)
60+
true ->
61+
uri
62+
end
63+
end
64+
65+
def root_path() do
66+
Path.join(__DIR__, "../") |> Path.expand()
67+
end
68+
69+
def get_file_content(file) do
70+
case File.read(file) do
71+
{:ok, content} ->
72+
content
73+
{:error, _} ->
74+
"404 not find!"
75+
end
76+
end
77+
78+
def get_content_type(request_path) do
79+
cond do
80+
request_path == "/" ->
81+
"text/html"
82+
request_path =~ ~r".html$|.htm$|.jsp$" ->
83+
"text/html"
84+
request_path =~ ~r".css$" ->
85+
"text/css"
86+
request_path =~ ~r".png$" ->
87+
"image/png"
88+
request_path =~ ~r".ico$" ->
89+
"image/x-icon"
90+
request_path =~ ~r".gif$" ->
91+
"image/gif"
92+
request_path =~ ~r".jpe$|.jpeg$" ->
93+
"image/jpeg"
94+
request_path =~ ~r".jpg$" ->
95+
"application/x-jpg"
96+
true ->
97+
"text/plain"
98+
end
99+
end
100+
101+
end

mix.exs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
defmodule Reacttutorial.Mixfile do
2+
use Mix.Project
3+
4+
def project do
5+
[app: :reacttutorial,
6+
version: "0.0.1",
7+
elixir: "~> 1.1",
8+
build_embedded: Mix.env == :prod,
9+
start_permanent: Mix.env == :prod,
10+
deps: deps]
11+
end
12+
13+
# Configuration for the OTP application
14+
#
15+
# Type "mix help compile.app" for more information
16+
def application do
17+
[applications: [:logger,:cowboy],
18+
mod: {ReactTutorial, []}]
19+
end
20+
21+
# Dependencies can be Hex packages:
22+
#
23+
# {:mydep, "~> 0.3.0"}
24+
#
25+
# Or git/path repositories:
26+
#
27+
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
28+
#
29+
# Type "mix help deps" for more examples and options
30+
defp deps do
31+
[{:cowboy, "~> 1.0" },
32+
{:plug, "~> 0.14" },
33+
{:poison, "~> 2.0"}]
34+
end
35+
end

0 commit comments

Comments
 (0)