diff --git a/.gitignore b/.gitignore
index e3274c5057b7..1a1aa568bca3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,9 @@ _test
 # IntelliJ
 .idea
 
+# MS VSCode
+.vscode
+
 # Architecture specific extensions/prefixes
 *.[568vq]
 [568vq].out
@@ -36,6 +39,7 @@ _testmain.go
 *.log
 
 /gitea
+/debug
 /integrations.test
 
 /bin
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e58d8e30702d..7422f43f1d9d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,6 +26,8 @@ It assumes you have followed the
 Sensitive security-related issues should be reported to
 [security@gitea.io](mailto:security@gitea.io).
 
+For configuring IDE or code editor to develop Gitea see [IDE and code editor configuration](contrib/ide/)
+
 ## Bug reports
 
 Please search the issues on the issue tracker with a variety of keywords
diff --git a/contrib/ide/README.md b/contrib/ide/README.md
new file mode 100644
index 000000000000..80b6a8aad97e
--- /dev/null
+++ b/contrib/ide/README.md
@@ -0,0 +1,12 @@
+# IDE and code editor configuration
+
+## Table of Contents
+- [IDE and code editor configuration](#ide-and-code-editor-configuration)
+  - [Microsoft Visual Studio Code](#microsoft-visual-studio-code)
+
+## Microsoft Visual Studio Code
+Download Microsoft Visual Studio Code at https://code.visualstudio.com/ and follow instructions at https://code.visualstudio.com/docs/languages/go to setup Go extension for it.
+
+Create new direcotry `.vscode` in Gitea root folder and copy contents of folder [contrib/ide/vscode](vscode/) to it. You can now use `Ctrl`+`Shift`+`B` to build gitea executable and `F5` to run it in debug mode.
+
+Supported on Debian, Ubuntu, Red Hat, Fedora, SUSE Linux, MacOS and Microsoft Windows.
diff --git a/contrib/ide/vscode/launch.json b/contrib/ide/vscode/launch.json
new file mode 100644
index 000000000000..af1594cd5d8a
--- /dev/null
+++ b/contrib/ide/vscode/launch.json
@@ -0,0 +1,31 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "Launch",
+      "type": "go",
+      "request": "launch",
+      "mode": "debug",
+      "buildFlags": "",
+      "port": 2345,
+      "host": "127.0.0.1",
+      "program": "${workspaceRoot}/main.go",
+      "env": {},
+      "args": ["web"],
+      "showLog": true
+    },
+    {
+      "name": "Launch (with SQLite3)",
+      "type": "go",
+      "request": "launch",
+      "mode": "debug",
+      "buildFlags": "-tags=\"sqlite\"",
+      "port": 2345,
+      "host": "127.0.0.1",
+      "program": "${workspaceRoot}/main.go",
+      "env": {},
+      "args": ["web"],
+      "showLog": true
+    }
+  ]
+}
diff --git a/contrib/ide/vscode/tasks.json b/contrib/ide/vscode/tasks.json
new file mode 100644
index 000000000000..8527d91c8f54
--- /dev/null
+++ b/contrib/ide/vscode/tasks.json
@@ -0,0 +1,51 @@
+{
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "taskName": "Build",
+      "type": "shell",
+      "command": "go",
+      "group": "build",
+      "presentation": {
+        "echo": true,
+        "reveal": "always",
+        "focus": false,
+        "panel": "shared"
+      },
+      "args": ["build"],
+      "linux": {
+        "args": [ "-o", "gitea", "${workspaceRoot}/main.go" ]
+      },
+      "osx": {
+        "args": [ "-o", "gitea", "${workspaceRoot}/main.go" ]
+      },
+      "windows": {
+        "args": [ "-o", "gitea.exe", "\"${workspaceRoot}\\main.go\""]
+      },
+      "problemMatcher": ["$go"]
+    },
+    {
+      "taskName": "Build (with SQLite3)",
+      "type": "shell",
+      "command": "go",
+      "group": "build",
+      "presentation": {
+        "echo": true,
+        "reveal": "always",
+        "focus": false,
+        "panel": "shared"
+      },
+      "args": ["build", "-tags=\"sqlite\""],
+      "linux": {
+        "args": ["-o", "gitea", "${workspaceRoot}/main.go"]
+      },
+      "osx": {
+        "args": ["-o", "gitea", "${workspaceRoot}/main.go"]
+      },
+      "windows": {
+        "args": ["-o", "gitea.exe", "\"${workspaceRoot}\\main.go\""]
+      },
+      "problemMatcher": ["$go"]
+    }
+  ]
+}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 721dd0f0f75c..4932f51a68d2 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -500,7 +500,11 @@ func DateLang(lang string) string {
 
 // execPath returns the executable path.
 func execPath() (string, error) {
-	file, err := exec.LookPath(os.Args[0])
+	execFile := os.Args[0]
+	if IsWindows && filepath.IsAbs(execFile) {
+		return filepath.Clean(execFile), nil
+	}
+	file, err := exec.LookPath(execFile)
 	if err != nil {
 		return "", err
 	}